非对称加密算法 - Java加密与安全
生活随笔
收集整理的這篇文章主要介紹了
非对称加密算法 - Java加密与安全
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
非對稱加密算法我們從DH算法中可以看到密鑰對是一種非常有用的加密算法
密鑰對中publicKey是可以公開的,而privateKey則是需要保密的,由此奠定了非對稱加密的基礎(chǔ)
非對稱加密就是加密和解密使用的是不同的密鑰,使用非對稱加密的時(shí)候,使用同一個(gè)公鑰和私鑰對才能夠正常的加密解密,1. 在加密的時(shí)候使用自己的私鑰加密,然后發(fā)送給對方2. 然后解密的時(shí)候使用自己的公鑰來解密
另一種方法是1. 使用對方的公鑰加密,然后發(fā)送給對方2. 解密的時(shí)候可以用自己的私鑰解密
非對稱加密的典型算法就是RSA算法,RSA算法是三個(gè)發(fā)明人的縮寫
package com.learn.securl;import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;import javax.crypto.Cipher;/*** 在非對稱加密的時(shí)候,* 我們先定義一個(gè)RSAKeyPair這個(gè)類* @author Leon.Sun**/
public class RSAKeyPair {/*** 私鑰* * 他包含了一個(gè)私鑰privateKey*/PrivateKey sk;/*** 公鑰* * 一個(gè)公鑰publicKey*/PublicKey pk;/*** 生成公鑰/私鑰對* * 我們在構(gòu)造方法中生成一個(gè)公鑰和私鑰對* @throws GeneralSecurityException*/public RSAKeyPair() throws GeneralSecurityException{/*** 創(chuàng)建公鑰和私鑰對的方法是* 通過KeyPairGenerator.getInstance然后傳入算法RSA*/KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");/*** 緊接著我們調(diào)用initialize方法* 然后傳入1024* 表示我們生成的密鑰長度是1024位*/kpGen.initialize(1024);/*** 緊接著我們調(diào)用generateKeyPair方法* 就生成了一個(gè)KeyPair*/KeyPair kp = kpGen.generateKeyPair();/*** 我們通過getPrivate和getPublic分別獲得privateKey和publicKey* 我們通常用pk來表示publicKey* 用sk表示privateKey*/this.sk = kp.getPrivate();this.pk = kp.getPublic();}/*** 從以保存的字節(jié)中(例如:讀取文件)恢復(fù)公鑰/私鑰* * 傳入的是字節(jié),* 我們可以從已保存的字節(jié)中恢復(fù)公鑰和私鑰* @param pk* @param sk* @throws GeneralSecurityException*/public RSAKeyPair(byte[] pk, byte[] sk) throws GeneralSecurityException{KeyFactory kf = KeyFactory.getInstance("RSA");/*** 恢復(fù)公鑰是構(gòu)造一個(gè)X509EncodedKeySpec對象*/X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(pk);/*** 然后就可以通過generatePublic方法來恢復(fù)一個(gè)公鑰*/this.pk = kf.generatePublic(pkSpec);/*** 而恢復(fù)私鑰則是通過PKCS8EncodedKeySpec來恢復(fù)私鑰*/PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(sk);this.sk = kf.generatePrivate(skSpec);}/*** 把私鑰導(dǎo)出為字節(jié)* * @return*/public byte[] getPrivateKey(){/*** 我們可以通過getPrivateKey方法可以把私鑰導(dǎo)出為一個(gè)字節(jié)*/return this.sk.getEncoded();}/*** 把公鑰導(dǎo)出為字節(jié)* @return*/public byte[] getPublicKey(){/*** 我們也可以通過getEncoded方法把公鑰導(dǎo)出為一個(gè)字節(jié)*/return this.pk.getEncoded();}/*** 用公鑰加密* @param message* @return* @throws GeneralSecurityException*/public byte[] encrypt(byte[] message) throws GeneralSecurityException{/*** 我們還是通過看Cipher.getInstance傳入RSA* 得到一個(gè)Cipher對象*/Cipher cipher = Cipher.getInstance("RSA");/*** 然后我們初始化ENCRYPT_MODE,用于加密* 這個(gè)時(shí)候我們傳入的是公鑰* 表示用公鑰加密*/cipher.init(Cipher.ENCRYPT_MODE, this.pk);/*** 最后doFinal就可以得到加密以后的密文*/return cipher.doFinal(message);}/*** 用私鑰解密 * * 我們再定義一個(gè)decrypt方法* @param input* @return* @throws GeneralSecurityException*/public byte[] decrypt(byte[] input) throws GeneralSecurityException{Cipher cipher = Cipher.getInstance("RSA");/*** 這個(gè)時(shí)候我們傳入的是DECRYPT_MODE* 并且傳入的是私鑰,表示用私鑰解密*/cipher.init(Cipher.DECRYPT_MODE, this.sk);return cipher.doFinal(input);}/*** 最后我們定義一個(gè)main方法來測試* @param args* @throws Exception*/public static void main(String[] args) throws Exception{// 明文:byte[] plain = "Hello,使用RSA非對稱加密算法對數(shù)據(jù)進(jìn)行加密!".getBytes();// 創(chuàng)建公鑰/私鑰對:/*** 我們首先創(chuàng)建一個(gè)RSAKeyPair對象*/RSAKeyPair rsa = new RSAKeyPair();// 加密:/*** 然后調(diào)用encrypt方法進(jìn)行加密*/byte[] encrypted = rsa.encrypt(plain);System.out.println("encrypted: " + Base64.getEncoder().encodeToString(encrypted));// 解密:/*** 然后調(diào)用decrypt方法進(jìn)行解密*/byte[] decrypted = rsa.decrypt(encrypted);System.out.println("decrypted: " + new String(decrypted, "UTF-8"));// 保存公鑰/私鑰:/*** 我們還把RSA的publicKey和privateKey導(dǎo)出為byte數(shù)組*/byte[] pk = rsa.getPublicKey();byte[] sk = rsa.getPrivateKey();System.out.println("pk: " + Base64.getEncoder().encodeToString(pk));System.out.println("sk: " + Base64.getEncoder().encodeToString(sk));// 重新恢復(fù)公鑰/私鑰:/*** 然后我們把byte數(shù)組重新恢復(fù)為公鑰和私鑰*/RSAKeyPair rsa2 = new RSAKeyPair(pk, sk);// 加密:byte[] encrypted2 = rsa2.encrypt(plain);System.out.println("encrypted: " + Base64.getEncoder().encodeToString(encrypted2));// 解密:byte[] decrypted2 = rsa2.decrypt(encrypted2);System.out.println("decrypted: " + new String(decrypted2, "UTF-8"));}
}
非對稱加密有以下的優(yōu)點(diǎn):1. 對稱加密需要協(xié)商密鑰,而非對稱加密可以安全的公開各自的公鑰2. 如果N個(gè)人之間需要通信的話,使用非對稱加密只需要每個(gè)人管理各自的密鑰對,總共需要N個(gè)密鑰對3. 而使用對稱加密需要N*(N-1)/密鑰,每個(gè)人需要管理N-1個(gè)密鑰
非對稱的缺點(diǎn)是運(yùn)算速度慢
如果只使用非對稱加密,不能防止中間人的攻擊最后我們總結(jié)一下:1. 非對稱加密是加密和解密使用的是不同的密鑰2. 只有同一個(gè)公鑰和私鑰才能夠正常的加密和解密3. 只使用非對稱加密是不能夠防止中間人的攻擊
?
總結(jié)
以上是生活随笔為你收集整理的非对称加密算法 - Java加密与安全的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 密钥交换算法 - Java加密与安全
- 下一篇: RSA签名算法 - Java加密与安全