使用rsa对明文加密与解密(私钥转pkcs8 格式问题)
公钥加密,私钥解密
/**
* 加密
*
* @param plaintext 明文
* @param publicKeyStr 公钥字符
* @return
* @throws Exception
*/
public static String rsaEncrypt(String plaintext, String publicKeyStr) throws Exception {
// 将公钥字符串和私钥字符串转换为 PublicKey 对象
PublicKey publicKey = getPublicKey(publicKeyStr);
// 使用公钥加密明文
byte[] encryptedBytes = encrypt(plaintext.getBytes(StandardCharsets.UTF_8), publicKey);
System.out.println("加密文本: " + base64Encode(encryptedBytes));
return base64Encode(encryptedBytes);
}
/**
* 加密
*
* @param encryptedText 加密密文
* @param privateKeyStr 私钥字符
* @return
* @throws Exception
*/
public static String rsaDecrypt(String encryptedText, String privateKeyStr) throws Exception {
// 将公钥字符串和私钥字符串转换为 PrivateKey 对象
PrivateKey privateKey = getPrivateKey(privateKeyStr);
// 使用私钥解密密文
byte[] decryptedBytes = decrypt(base64Decode(encryptedText), privateKey);
System.out.println("解密文本: " + new String(decryptedBytes, StandardCharsets.UTF_8));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
/**
* 将公钥字符串转换为 PublicKey 对象
*
* @param publicKeyStr
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(String publicKeyStr) throws Exception {
byte[] keyBytes = base64Decode(publicKeyStr);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
/**
* 将私钥字符串转换为 PrivateKey 对象
*
* @param privateKeyStr
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKey(String privateKeyStr) throws Exception {
// 添加 Bouncy Castle 作为安全提供程序
Security.addProvider(new BouncyCastleProvider());
byte[] keyBytes = base64Decode(privateKeyStr);
//pkcs1格式 转 pkcs8格式
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
/**
* 使用公钥加密
*
* @param plaintext
* @param publicKey
* @return
* @throws Exception
*/
public static byte[] encrypt(byte[] plaintext, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(plaintext);
}
/**
* 使用私钥解密
*
* @param ciphertext
* @param privateKey
* @return
* @throws Exception
*/
public static byte[] decrypt(byte[] ciphertext, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(ciphertext);
}
/**
* Base64 编码
*
* @param data
* @return
*/
public static String base64Encode(byte[] data) {
return Base64.getEncoder().encodeToString(data);
}
/**
* Base64 解码
*
* @param data
* @return
*/
public static byte[] base64Decode(String data) {
return Base64.getDecoder().decode(data);
}
测试
public static void main(String[] args) throws Exception {
// 明文
String plaintext = "123456";
// 使用公钥加密明文
String s = rsaEncrypt(plaintext, publicKeyStr);
System.out.println("加密文本: " + s);
System.out.println("解密文本: " + rsaDecrypt(s, privateKeyStr));
String sign = sign(plaintext);
System.out.println("签名结果:" + sign);
boolean verify = verify(plaintext, sign);
System.out.println("验证签名结果:" + verify);
}
秘钥格式
PKCS1的文件头格式 -----BEGIN RSA PRIVATE KEY-----
PKCS8的文件头格式 -----BEGIN PRIVATE KEY-----
签名
/**
* 签名
*
* @param plaintext 需要签名的明文
* @return 返回签名信息
* @throws Exception
*/
public static String sign(String plaintext) throws Exception {
byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// 创建Signature对象并初始化为签名模式
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
// 要签名的数据
byte[] dataToSign = plaintext.getBytes(StandardCharsets.UTF_8);
// 更新数据并签名
signature.update(dataToSign);
byte[] signatureBytes = signature.sign();
// 将签名结果以Base64编码的形式输出
String signatureBase64 = Base64.getEncoder().encodeToString(signatureBytes);
System.out.println("RSA签名结果:" + signatureBase64);
return signatureBase64;
}
验证签名
/**
* 验证签名
*
* @param plaintext 明文
* @param decodeSrc 签名结果的Base64编码
* @return 返回签名结果
* @throws Exception
*/
public static boolean verify(String plaintext, String decodeSrc) throws Exception {
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// 创建Signature对象并初始化为验签模式
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
// 原始数据和签名数据
byte[] originalData = plaintext.getBytes(StandardCharsets.UTF_8);
byte[] signatureBytes = Base64.getDecoder().decode(decodeSrc);
// 更新数据并验证签名
signature.update(originalData);
boolean isValid = signature.verify(signatureBytes);
if (isValid) {
System.out.println("RSA签名验证成功");
} else {
System.out.println("RSA签名验证失败");
}
return isValid;
}
注意:
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
这个是构造一个对象,并没有转换pkcs8 格式的操作
在执行转换前加上这行就可以了
Security.addProvider(new BouncyCastleProvider());
如果秘钥放在yml文件中需要注意以\换行