package com.zjmzxfzhl.common.core.util;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
;
/**
* 公鑰和私鑰是成對的,公鑰加密要用私鑰解密,私鑰加密要用公鑰解密。每次加密結(jié)果是變化的。
* 1、公鑰加密,私鑰解密用于信息加密。
* 2、私鑰加密,公鑰解密。
* 3、私鑰簽名,公鑰驗證。在https中公鑰任何人都有,用私鑰加密意義不大,還不如使用簽名。
* 簽名實際上是對明文的摘要做了加密。收到的人會收到明文和簽名,利用公鑰可以進(jìn)行驗證真?zhèn)?,?shù)字簽名保證信息是服務(wù)端發(fā)的,并且沒有遭到篡改。
* 前面兩點(diǎn)是加密,后面一點(diǎn)是認(rèn)證。兩者的側(cè)重點(diǎn)是不同的。后面一點(diǎn)鑒別服務(wù)端的真?zhèn)? * @2023年9月12日
* https://blog.csdn.net/u014644574/article/details/128810787
*/
public class RSAUtil {
//定義加密方式
public static final String KEY_RSA = "RSA";
//定義簽名算法
private final static String KEY_RSA_SIGNATURE = "MD5withRSA";
//公鑰
public final static String publicKey = "..........";
//私鑰
public final static String privateKey = ".................";
public static void main(String[] args) {
//生成新的公私密鑰對
// init();
String str = "你好, RSA!";
// 公鑰加密,私鑰解密
String enStr1 = RSAUtil.encryptByPublic(str, publicKey);
System.out.println("公鑰加密后:" + enStr1);
String deStr1 = RSAUtil.decryptByPrivate(enStr1, privateKey);
System.out.println("私鑰解密后:" + deStr1);
// // 私鑰加密,公鑰解密
// String enStr2 = RSAUtil.encryptByPrivate(str, privateKey);
// System.out.println("私鑰加密后:" + enStr2);
// String deStr2 = RSAUtil.decryptByPublic(enStr2, publicKey);
// System.out.println("公鑰解密后:" + deStr2);
// // 產(chǎn)生簽名
// String sign = sign(enStr2, privateKey);
// System.out.println("簽名:" + sign);
// // 驗證簽名
// boolean status = verify(enStr2, publicKey, sign);
// System.out.println("驗證簽名狀態(tài):" + status);
}
/**
* 生成公私密鑰對
* @date:2018年10月31日 上午11:16:41
*/
public static void init() {
try {
KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);
//設(shè)置密鑰對的bit數(shù),越大越安全,但速度減慢,一般使用512或1024
generator.initialize(1024);
KeyPair keyPair = generator.generateKeyPair();
// 獲取公鑰
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 獲取私鑰
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// Base64編碼的公鑰字符串
String publicKeyStr = encryptBase64(publicKey.getEncoded());
//Base64編碼的私鑰字符串
String privateKeyStr = encryptBase64(privateKey.getEncoded());
// 打印密鑰對
System.out.println("publicKey=" + publicKeyStr);
System.out.println("privateKey=" + privateKeyStr);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* BASE64 解碼
* @param key 需要Base64解碼的字符串
* @date:2018年10月31日 上午11:17:46
*/
public static byte[] decryptBase64(String key) {
return Base64.getDecoder().decode(key);
}
/**
* BASE64 編碼
* @param key 需要Base64編碼的字節(jié)數(shù)組
* @date:2018年10月31日 上午11:18:03
*/
public static String encryptBase64(byte[] key) {
return new String(Base64.getEncoder().encode(key));
}
/**
* 公鑰加密
* @param encryptingStr 字符串
* @param publicKeyStr 公鑰
* @date:2018年10月31日 上午11:18:17
*/
public static String encryptByPublic(String encryptingStr, String publicKeyStr) {
try {
// 將公鑰由字符串轉(zhuǎn)為UTF-8格式的字節(jié)數(shù)組
byte[] publicKeyBytes = decryptBase64(publicKeyStr);
// 獲得公鑰
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
// 取得待加密數(shù)據(jù)
byte[] data = encryptingStr.getBytes(StandardCharsets.UTF_8);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PublicKey publicKey = factory.generatePublic(keySpec);
// 對數(shù)據(jù)加密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 返回加密后由Base64編碼的加密信息
return encryptBase64(cipher.doFinal(data));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 私鑰解密
* @param encryptedStr 字符串
* @param privateKeyStr 私鑰
* @date:2018年10月31日 上午11:18:36
*/
public static String decryptByPrivate(String encryptedStr, String privateKeyStr) {
try {
// 對私鑰解密
byte[] privateKeyBytes = decryptBase64(privateKeyStr);
// 獲得私鑰
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
// 獲得待解密數(shù)據(jù)
byte[] data = decryptBase64(encryptedStr);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PrivateKey privateKey = factory.generatePrivate(keySpec);
// 對數(shù)據(jù)解密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// 返回UTF-8編碼的解密信息
return new String(cipher.doFinal(data), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 私鑰加密
* @param encryptingStr 字符串
* @param privateKeyStr 私鑰
* @date:2018年10月31日 上午11:18:57
*/
public static String encryptByPrivate(String encryptingStr, String privateKeyStr) {
try {
byte[] privateKeyBytes = decryptBase64(privateKeyStr);
// 獲得私鑰
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
// 取得待加密數(shù)據(jù)
byte[] data = encryptingStr.getBytes(StandardCharsets.UTF_8);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PrivateKey privateKey = factory.generatePrivate(keySpec);
// 對數(shù)據(jù)加密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
// 返回加密后由Base64編碼的加密信息
return encryptBase64(cipher.doFinal(data));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 公鑰解密
* @param encryptedStr 字符串
* @param publicKeyStr 公鑰
* @date:2018年10月31日 上午11:19:07
*/
public static String decryptByPublic(String encryptedStr, String publicKeyStr) {
try {
// 對公鑰解密
byte[] publicKeyBytes = decryptBase64(publicKeyStr);
// 取得公鑰
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
// 取得待加密數(shù)據(jù)
byte[] data = decryptBase64(encryptedStr);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PublicKey publicKey = factory.generatePublic(keySpec);
// 對數(shù)據(jù)解密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
// 返回UTF-8編碼的解密信息
return new String(cipher.doFinal(data), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 用私鑰對私鑰加密數(shù)據(jù)進(jìn)行簽名
* @param encryptedStr 私鑰加密后的字符串
* @param privateKey 私鑰
* @date:2018年10月31日 上午11:19:37
*/
public static String sign(String encryptedStr, String privateKey) {
String str = "";
try {
//將私鑰加密數(shù)據(jù)字符串轉(zhuǎn)換為字節(jié)數(shù)組
byte[] data = encryptedStr.getBytes(StandardCharsets.UTF_8);
// 解密由base64編碼的私鑰
byte[] bytes = decryptBase64(privateKey);
// 構(gòu)造PKCS8EncodedKeySpec對象
PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
// 指定的加密算法
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
// 取私鑰對象
PrivateKey key = factory.generatePrivate(pkcs);
// 用私鑰對信息生成數(shù)字簽名
Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
signature.initSign(key);
signature.update(data);
str = encryptBase64(signature.sign());
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* 校驗數(shù)字簽名
* @param encryptedStr 私鑰加密后的字符串
* @param publicKey 公鑰
* @param sign 簽名
* @date:2018年10月31日 上午11:19:50
*/
public static boolean verify(String encryptedStr, String publicKey, String sign) {
try {
//將私鑰加密數(shù)據(jù)字符串轉(zhuǎn)換為字節(jié)數(shù)組
byte[] data = encryptedStr.getBytes(StandardCharsets.UTF_8);
// 解密由base64編碼的公鑰
byte[] bytes = decryptBase64(publicKey);
// 構(gòu)造X509EncodedKeySpec對象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
// 指定的加密算法
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
// 取公鑰對象
PublicKey key = factory.generatePublic(keySpec);
// 用公鑰驗證數(shù)字簽名
Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
signature.initVerify(key);
signature.update(data);
return signature.verify(decryptBase64(sign));
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
RSA非對稱加密解密工具類
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 背景: 使用公鑰加密數(shù)據(jù),然后使用私鑰解密。網(wǎng)上找的現(xiàn)成的java方法,然后轉(zhuǎn)成kotlin。
- 基于kotlin語言的RSA非對稱加密解密與分段加密解密 RSA非對稱加密 RSA非對稱加密的具體算法與來源我就不...
- 沒有那么多廢話,我知道這是一個簡單的加密工具類,但是網(wǎng)上的工具類很雜,我這至少保證全都是自己試驗過的可以直接使用!...
- 之前寫過一篇java實現(xiàn)AES對稱加密解密[http://www.itdecent.cn/p/c728d612c...