公钥加密,私钥解密
/** * 加密 * * @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文件中需要注意以\换行
标签:Exception,return,String,plaintext,解密,rsa,byte,明文,throws From: https://www.cnblogs.com/ckfeng/p/17784574.html