簡介
① 非對稱加密算法又稱現代加密算法
。
② 非對稱加密是計算機通信安全的基石,保證了加密數據不會被破解
。
③ 與對稱加密算法不同,非對稱加密算法需要兩個密鑰:公開密鑰(publickey)
和私有密(privatekey)
④ 公開密鑰和私有密鑰是一對
⑤ 如果用公開密鑰
對數據進行加密
,只有用對應的私有密鑰
才能解密
。
⑥ 如果用私有密鑰
對數據進行加密
,只有用對應的公開密鑰
才能解密
。
⑦ 因爲加密和解密使用的是兩個不同
的密鑰,所以這種算法叫作非對稱加密算法
。
示例
首先生成密鑰對, 公鑰爲(5,14), 私鑰爲(11,14)
現在A希望將原文2發送給B
A使用公鑰加密數據. 2的5次方mod 14 = 4 , 將密文4發送給B
B使用私鑰解密數據. 4的11次方mod14 = 2, 得到原文2
特點
加密和解密使用不同的密鑰
如果使用私鑰加密, 只能使用公鑰解密
如果使用公鑰加密, 只能使用私鑰解密
處理數據的速度較慢, 因爲安全級別高
常見算法
RSA
ECC
私鑰加密公鑰解密
package com.atguigu.rsa;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.commons.io.FileUtils;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
/**
* RSAdemo
*
* @Author: 尚硅谷
* @CreateTime: 2020-04-12
* @Description:
*/
public class RSAdemo {
public static void main(String[] args) throws Exception {
String input = "硅谷";
// 加密算法
String algorithm = "RSA";
// 創建密鑰對生成器對象
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 生成密鑰對
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 生成私鑰
PrivateKey privateKey = keyPair.getPrivate();
// 生成公鑰
PublicKey publicKey = keyPair.getPublic();
// 獲取私鑰字節數組
byte[] privateKeyEncoded = privateKey.getEncoded();
// 獲取公鑰字節數組
byte[] publicKeyEncoded = publicKey.getEncoded();
// 對公私鑰進行base64編碼
String privateKeyString = Base64.encode(privateKeyEncoded);
String publicKeyString = Base64.encode(publicKeyEncoded);
// 創建加密對象
// 參數表示加密算法
Cipher cipher = Cipher.getInstance(algorithm);
// 初始化加密
// 第一個參數:加密的模式
// 第二個參數:使用私鑰進行加密
cipher.init(Cipher.ENCRYPT_MODE,privateKey);
// 私鑰加密
byte[] bytes = cipher.doFinal(input.getBytes());
System.out.println(Base64.encode(bytes));
// 私鑰進行解密
cipher.init(Cipher.DECRYPT_MODE,publicKey);
// 對密文進行解密,不需要使用base64,因爲原文不會亂碼
byte[] bytes1 = cipher.doFinal(bytes);
System.out.println(new String(bytes1));
}
}
保存公鑰和私鑰
前面代碼每次都會生成 加密和解密 ,咱們需要把加密和解密的方法全部到本地的根目錄下面。
import java.io.File;
import java.nio.charset.Charset;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import org.apache.commons.io.FileUtils;
import com.sun.org.apache.xml.internal.security.utils.Base64;
public class RSAdemo1 {
public static void main(String[] args) throws Exception {
// 加密算法
String algorithm = "RSA";
//生成密鑰對並保存在本地文件中
generateKeyToFile(algorithm, "a.pub", "a.pri");
}
/**
* 生成密鑰對並保存在本地文件中
*
* @param algorithm : 算法
* @param pubPath : 公鑰保存路徑
* @param priPath : 私鑰保存路徑
* @throws Exception
*/
private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
// 獲取密鑰對生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 獲取密鑰對
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 獲取公鑰
PublicKey publicKey = keyPair.getPublic();
// 獲取私鑰
PrivateKey privateKey = keyPair.getPrivate();
// 獲取byte數組
byte[] publicKeyEncoded = publicKey.getEncoded();
byte[] privateKeyEncoded = privateKey.getEncoded();
// 進行Base64編碼
String publicKeyString = Base64.encode(publicKeyEncoded);
String privateKeyString = Base64.encode(privateKeyEncoded);
// 保存文件
FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.forName("UTF-8"));
FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.forName("UTF-8"));
}
}
讀取祕鑰加密解密
import java.io.File;
import java.nio.charset.Charset;
import java.security.Key;
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 javax.crypto.Cipher;
import org.apache.commons.io.FileUtils;
import com.sun.org.apache.xml.internal.security.utils.Base64;
public class RSAdemo {
public static void main(String[] args) throws Exception {
String input = "硅谷";
// 加密算法
String algorithm = "RSA";
PrivateKey privateKey = getPrivateKey("a.pri", algorithm);
PublicKey publicKey = getPublicKey("a.pub", algorithm);
String s = encryptRSA(algorithm, privateKey, input);
String s1 = decryptRSA(algorithm, publicKey, s);
System.out.println(s1);
}
public static PublicKey getPublicKey(String pulickPath, String algorithm) throws Exception {
// 將文件內容轉爲字符串
String publicKeyString = FileUtils.readFileToString(new File(pulickPath), Charset.defaultCharset());
// 獲取密鑰工廠
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 構建密鑰規範 進行Base64解碼
X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyString));
// 生成公鑰
return keyFactory.generatePublic(spec);
}
public static PrivateKey getPrivateKey(String priPath, String algorithm) throws Exception {
// 將文件內容轉爲字符串
String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset());
// 獲取密鑰工廠
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 構建密鑰規範 進行Base64解碼
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString));
// 生成私鑰
return keyFactory.generatePrivate(spec);
}
/**
* 生成密鑰對並保存在本地文件中
*
* @param algorithm : 算法
* @param pubPath : 公鑰保存路徑
* @param priPath : 私鑰保存路徑
* @throws Exception
*/
public static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
// 獲取密鑰對生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 獲取密鑰對
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 獲取公鑰
PublicKey publicKey = keyPair.getPublic();
// 獲取私鑰
PrivateKey privateKey = keyPair.getPrivate();
// 獲取byte數組
byte[] publicKeyEncoded = publicKey.getEncoded();
byte[] privateKeyEncoded = privateKey.getEncoded();
// 進行Base64編碼
String publicKeyString = Base64.encode(publicKeyEncoded);
String privateKeyString = Base64.encode(privateKeyEncoded);
// 保存文件
FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.forName("UTF-8"));
FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.forName("UTF-8"));
}
/**
* 解密數據
*
* @param algorithm : 算法
* @param encrypted : 密文
* @param key : 密鑰
* @return : 原文
* @throws Exception
*/
public static String decryptRSA(String algorithm, Key key, String encrypted) throws Exception {
// 創建加密對象
// 參數表示加密算法
Cipher cipher = Cipher.getInstance(algorithm);
// 私鑰進行解密
cipher.init(Cipher.DECRYPT_MODE, key);
// 由於密文進行了Base64編碼, 在這裏需要進行解碼
byte[] decode = Base64.decode(encrypted);
// 對密文進行解密,不需要使用base64,因爲原文不會亂碼
byte[] bytes1 = cipher.doFinal(decode);
return new String(bytes1);
}
/**
* 使用密鑰加密數據
*
* @param algorithm : 算法
* @param input : 原文
* @param key : 密鑰
* @return : 密文
* @throws Exception
*/
public static String encryptRSA(String algorithm, Key key, String input) throws Exception {
// 創建加密對象
// 參數表示加密算法
Cipher cipher = Cipher.getInstance(algorithm);
// 初始化加密
// 第一個參數:加密的模式
// 第二個參數:使用私鑰進行加密
cipher.init(Cipher.ENCRYPT_MODE, key);
// 私鑰加密
byte[] bytes = cipher.doFinal(input.getBytes());
// 對密文進行Base64編碼
return Base64.encode(bytes);
}
}