RSA是最流行的非对称加密算法之一,RSA中的公钥和私钥需要结合在一起工作,公钥用来对数据块加密,对应的私钥才能用来解密。
话不多说,直接上代码简单明了:
1、RSA的帮助类
package rsademo.util;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
//todo RSA 帮助类
public class RSAUtil {
//todo 生成密钥对:密钥对中包含公钥和私钥
public static KeyPair getKeyPair() throws NoSuchAlgorithmException, UnsupportedEncodingException {
//todo 获得RSA密钥对的生成器实例
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
//todo 一个安全的随机数
SecureRandom secureRandom = new SecureRandom(String.valueOf(System.currentTimeMillis()).getBytes("utf-8"));
//todo 这里可以是1024、2048 初始化一个密钥对
keyPairGenerator.initialize(2048, secureRandom);
//todo 获得密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
return keyPair;
}
//todo 获取公钥 进行Base64编码,返回Base64编码后的字符串
public static String getPublicKey(KeyPair keyPair) {
PublicKey publicKey = keyPair.getPublic();
byte[] bytes = publicKey.getEncoded();
return Base64.getEncoder().encodeToString(bytes);
}
//todo 获取私钥 进行Base64编码,返回Base64编码后的字符串
public static String getPrivateKey(KeyPair keyPair) {
PrivateKey privateKey = keyPair.getPrivate();
byte[] bytes = privateKey.getEncoded();
return Base64.getEncoder().encodeToString(bytes);
}
//todo 将Base64编码后的公钥转换成PublicKey对象
public static PublicKey stringPublicKey(String pubStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] bytes = Base64.getDecoder().decode(pubStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
//todo 将base64编码后的私钥转换成PrivateKey对象
public static PrivateKey stringPrivateKey(String priStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] bytes = Base64.getDecoder().decode(priStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
//todo 公钥加密 待加密内容 byte[] 加密所需要的公钥对象PublicKey 加密后的字节数组 byte[]
public static byte[] publicEncryType(byte[] content, PublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytes = cipher.doFinal(content);
return bytes;
}
//todo 私钥解密 待解密的内容 byte[] 加密需要的私钥对象PrivateKey 解密后的字节数组 byte[]
public static byte[] privateEncryType(byte[] content, PrivateKey privateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] bytes = cipher.doFinal(content);
return bytes;
}
}
2、RSA 测试类
package rsademo.test;
import rsademo.util.RSAUtil;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
//todo RSA 测试类
public class RSATest {
public static void main(String[] args) {
//todo 需要加密的内容
String num = "愿你阳光里像个孩子,风雨中是个大人!";
System.out.println("加密前的内容: " + num);
try {
//todo 获取密钥对
KeyPair keyPair = RSAUtil.getKeyPair();
//todo 获得Base64加密后的公钥和私钥
String pubKey = RSAUtil.getPublicKey(keyPair);
String priKey = RSAUtil.getPrivateKey(keyPair);
//todo 输出Base64加密后的公钥和私钥
System.out.println("加密后的公钥:" + pubKey + "\n" + "加密后的私钥:" + priKey);
//todo 获取原始的公钥和私钥,以字符串的方式打印出来
PublicKey publicKey = RSAUtil.stringPublicKey(pubKey);
PrivateKey privateKey = RSAUtil.stringPrivateKey(priKey);
System.out.println("原始公钥:" + publicKey + "\n" + "原始私钥:" + privateKey);
//todo 公钥加密 私钥解密
byte[] pub = RSAUtil.publicEncryType(num.getBytes(), publicKey);
System.out.println("Base64加密后的公钥字符串:" + Base64.getEncoder().encodeToString(pub));
byte[] pri = RSAUtil.privateEncryType(pub, privateKey);
System.out.println("私钥解密后的原始字符串: " + new String(pri));
String priStr = new String(pri, "UTF-8");
if (num.equals(priStr)) {
System.out.println("Verification by");
} else {
System.out.println("Verification failed");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、结果