文章目录
说明RSA加解密测试代码打印输出说明
1:下面代码参考自《JAVA加密解密的艺术》,有部分修改,详见原理见原书
2:下面代码是RSA在JAVA中API级别的代码实现,具体实现原理见前面章节
3:下面代码中只需要JDK即可,其中为了便于阅读使用了commons-codec中Base64编码
4:公钥密码既可以公钥加密私钥解密,又可以私钥加密公钥解密,但注意加密解密必须是同一个密钥对
RSA加解密
import javax.crypto.Cipher;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.HashMap;import java.util.Map;/*** @Description: RSA加解密操作(公钥加密私钥解密-私钥加密公钥解密)* @Author: ZhangYu* @Date: /11/18*/public class RSACoder {//公钥密码密钥算法public static final String KEY_ALGORITHM = "RSA";//公钥private static final String PUBLIC_KEY = "RSAPublicKey";//私钥private static final String PRIVATE_KEY = "RSAPrivateKey";/*** RSA密钥长度* 默认1024位* 密钥长度必须是64的倍数* 范围在512-65536位之间*/private static final int KEY_SIZE = 512;/*** @Description: 私钥解密* @Param: data 待解密数据* @Param: key 私钥* @return: byte[] 解密数据* @Author: ZhangYu* @Date: /11/18*/public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {//获取私钥PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成私钥PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);//对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** @Description: 公钥解密* @Param: data 待解密数据* @Param: key 公钥* @return: byte[] 解密数据* @Author: ZhangYu* @Date: /11/18*/public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {// 取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成公钥PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);// 对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** @Description: 公钥加密* @Param: data 待加密数据* @Param: key 公钥* @return: byte[] 加密数据* @Author: ZhangYu* @Date: /11/18*/public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {//取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);//对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** @Description: 私钥加密* @Param: data 待加密数据* @Param: key 私钥* @return: byte[] 加密数据* @Author: ZhangYu* @Date: /11/18*/public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {//取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成私钥PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);//对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** @Description: 获取私钥* @Param: keyNap 秘钥对* @return: byte[] 私钥* @Author: ZhangYu* @Date: /11/18* @Throws:*/public static byte[] getPrivateKey(Map<String, Object> keyNap) throws Exception {Key key = (Key) keyNap.get(PRIVATE_KEY);return key.getEncoded();}/*** @Description: 获取公钥* @Param: keyMap 秘钥对* @return: byte[] 公钥* @Author: ZhangYu* @Date: /11/18* @Throws:*/public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return key.getEncoded();}/*** @Description: 初始化秘钥* @return: Map 秘钥对* @Author: ZhangYu* @Date: /11/18*/public static Map<String, Object> initKey() throws Exception {//实例化密钥对生成器KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);//初始化密钥对生成器keyPairGen.initialize(KEY_SIZE);//生成密钥对KeyPair keyPair = keyPairGen.generateKeyPair();//公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//封装密钥Map<String, Object> keyMap = new HashMap<>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}}
测试代码
import mons.codec.binary.Base64;import org.junit.BeforeClass;import org.junit.Test;import java.nio.charset.Charset;import java.util.Map;/*** @Description: RSA密码算法测试* @Author: ZhangYu* @Date: /11/18*/public class RSACoderTest {//公钥private static byte[] publicKey;//私钥private static byte[] privateKey;@BeforeClasspublic static void setUp() throws Exception {//初始化密钥Map<String, Object> keyPair = RSACoder.initKey();//获取公钥publicKey = RSACoder.getPublicKey(keyPair);//获取私钥privateKey = RSACoder.getPrivateKey(keyPair);//打印输出私钥和公钥编码字符串System.out.println("公钥:\n" + Base64.encodeBase64String(publicKey));System.out.println("私钥:\n" + Base64.encodeBase64String(privateKey));}/*** @Description: 私钥加密-公钥解密* @return: void* @Author: ZhangYu* @Date: /11/18*/@Testpublic void test1() throws Exception {System.out.println("\n私钥加密-公钥解密");//明文String input = "Hello 密码-私钥加密-公钥解密";byte[] data = input.getBytes();//私钥加密byte[] ciphertext = RSACoder.encryptByPrivateKey(data, privateKey);System.out.println("加密后密文\n" + Base64.encodeBase64String(ciphertext));//公钥解密byte[] plaintext = RSACoder.decryptByPublicKey(ciphertext, publicKey);System.out.println("解密后明文\n" + new String(plaintext, Charset.defaultCharset()));}/*** @Description: 公钥加密-私钥解密* @return: void* @Author: ZhangYu* @Date: /11/18*/@Testpublic void test2() throws Exception {System.out.println("\n公钥加密-私钥解密");//明文String input = "Hello 密码-公钥加密-私钥解密";byte[] data = input.getBytes();//公钥加密byte[] ciphertext = RSACoder.encryptByPublicKey(data, publicKey);System.out.println("加密后密文\n" + Base64.encodeBase64String(ciphertext));//私钥解密byte[] plaintext = RSACoder.decryptByPrivateKey(ciphertext, privateKey);System.out.println("解密后明文\n" + new String(plaintext, Charset.defaultCharset()));}}