当前位置:   article > 正文

Java实现RSA加密_java rsa加密

java rsa加密

一、什么是RSA?


RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。所以这个算法取自他们三位的姓名首字母。

RSA是目前最具有影响力的公钥加密算法,它的原理基于一个简单的数论事实:将两个大质数相乘十分简单,但是想要对它们的乘积进行分解却异常困难。这里的乘积一般公开作为密钥。只要密钥的长度足够大(一般1024位,也有2048位),基本上不可能从公钥信息推出私钥信息。

RSA使用“密钥对”对数据进行加密解密,在加密解密前需要先生成公钥(public key)和私钥(private key)

公钥:用于加密数据

私钥:用于解密数据

RSA中加密和加签有什么区别?

加密:公钥放在客户端,使用公钥对数据进行加密,服务端拿到数据后用私钥进行解密。

加签:私钥放在客户端,使用私钥对数据进行加签,服务端拿到数据后用公钥进行验签。

前者完全为了加密。后者主要是为了防止恶意攻击,让服务器辨别哪些是真正的请求,哪些是恶意的请求。

RSA是非对称加密算法,因为加密和解密的密钥不是同一个。

二、常用加解密


用到的常用字符串提取出来

  1. private final static String RSA_ALGORITHM = "RSA";
  2. private final static String SIGNATURE_ALGORITHM = "MD5withRSA";
  3. private final static String RSA_PUBLIC_KEY = "RSAPublicKey";
  4. private final static String RSA_PRIVATE_KEY = "RSAPrivateKey";

base64对二进制数据进行编码解码

  1. public static String encodeBase64(byte[] binaryData) {
  2. Encoder encoder = Base64.getEncoder();
  3. return encoder.encodeToString(binaryData);
  4. }
  5. public static byte[] decodeBase64(String encoded) {
  6. Decoder decoder = Base64.getDecoder();
  7. return decoder.decode(encoded);
  8. }

获取公钥私钥键值对

  1. public static Map<String,Object> getKey() throws NoSuchAlgorithmException{
  2. // 因为只存公钥和私钥,所以指明Map的长度是2
  3. Map<String,Object> keyMap = new HashMap<String,Object>(2);
  4. // 获取RSA算法实例
  5. KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA_ALGORITHM);
  6. // 1024代表密钥二进制位数
  7. keyPairGen.initialize(1024);
  8. // 产生KeyPair工厂
  9. KeyPair keyPair = keyPairGen.generateKeyPair();
  10. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  11. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  12. keyMap.put(RSA_PUBLIC_KEY, publicKey);
  13. keyMap.put(RSA_PRIVATE_KEY, privateKey);
  14. return keyMap;
  15. }

加密解密

  1. /**
  2. * 使用私钥对数据进行加密
  3. */
  4. public static byte[] encryptPrivateKey(byte[] binaryData, String privateKey) throws Exception {
  5. byte[] keyBytes = decodeBase64(privateKey);
  6. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  7. // 获取RSA算法实例
  8. KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
  9. Key priKey = keyFactory.generatePrivate(keySpec);
  10. // 初始化加密器
  11. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  12. cipher.init(Cipher.ENCRYPT_MODE, priKey);
  13. return cipher.doFinal(binaryData);
  14. }
  15. /**
  16. * 使用公钥对数据进行加密
  17. */
  18. public static byte[] encryptPublicKey(byte[] binaryData, String publicKey) throws Exception {
  19. byte[] keyBytes = decodeBase64(publicKey);
  20. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  21. // 获取RSA算法实例
  22. KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
  23. Key pubKey = keyFactory.generatePublic(keySpec);
  24. // 初始化加密器
  25. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  26. cipher.init(Cipher.ENCRYPT_MODE, pubKey);
  27. return cipher.doFinal(binaryData);
  28. }
  29. /**
  30. * 使用私钥对数据进行解密
  31. */
  32. public static byte[] decryptPrivateKey(byte[] binaryData, String privateKey) throws Exception {
  33. byte[] keyBytes = decodeBase64(privateKey);
  34. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  35. // 获取RSA算法实例
  36. KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
  37. Key priKey = keyFactory.generatePrivate(keySpec);
  38. // 初始化加密器
  39. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  40. cipher.init(Cipher.DECRYPT_MODE, priKey);
  41. return cipher.doFinal(binaryData);
  42. }
  43. /**
  44. * 使用公钥对数据进行解密
  45. */
  46. public static byte[] decryptPublicKey(byte[] binaryData, String publicKey) throws Exception {
  47. byte[] keyBytes = decodeBase64(publicKey);
  48. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  49. // 获取RSA算法实例
  50. KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
  51. Key pubKey = keyFactory.generatePublic(x509KeySpec);
  52. // 初始化加密器
  53. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  54. cipher.init(Cipher.DECRYPT_MODE, pubKey);
  55. return cipher.doFinal(binaryData);
  56. }

RSA还可以对指定内容进行加签验签

  1. /**
  2. * 使用私钥对数据进行签名
  3. */
  4. public static String sign(byte[] binaryData, String privateKey)
  5. throws Exception {
  6. byte[] keyBytes = decodeBase64(privateKey);
  7. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  8. // 获取RSA算法实例
  9. KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
  10. PrivateKey priKey = keyFactory.generatePrivate(keySpec);
  11. // 获取签名算法
  12. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  13. signature.initSign(priKey);
  14. signature.update(binaryData);
  15. return encodeBase64(signature.sign());
  16. }
  17. /**
  18. * 使用公钥对数据签名进行验证
  19. */
  20. public static boolean verify(byte[] binaryData, String publicKey, String sign)
  21. throws Exception {
  22. byte[] keyBytes = decodeBase64(publicKey);
  23. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  24. // 获取RSA算法实例
  25. KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
  26. PublicKey pubKey = keyFactory.generatePublic(keySpec);
  27. // 获取签名算法
  28. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  29. signature.initVerify(pubKey);
  30. signature.update(binaryData);
  31. return signature.verify(decodeBase64(sign));
  32. }

三、测试

  1. public static void main(String[] args) throws Exception {
  2. // 1.获取公钥私钥
  3. Map<String,Object> map = getKey();
  4. System.out.println("公钥:"+getPublicKey(map));
  5. System.out.println("私钥:"+getPrivateKey(map));
  6. String content = "未加密数据";
  7. System.out.println("============ 分隔符 ===========");
  8. // 2.使用私钥加密
  9. byte[] encodeContent = encryptPrivateKey(content.getBytes(),getPrivateKey(map));
  10. System.out.println("私钥加密后的数据:"+new String(encodeContent));
  11. // 3.使用公钥解密
  12. byte[] decodeContent = decryptPublicKey(encodeContent,getPublicKey(map));
  13. System.out.println("公钥解密后的数据:"+new String(decodeContent));
  14. System.out.println("============ 分隔符 ===========");
  15. // 4.使用公钥加密
  16. byte[] encodeContent2 = encryptPublicKey(content.getBytes(),getPublicKey(map));
  17. System.out.println("公钥加密后的数据:"+new String(encodeContent2));
  18. // 5.使用私钥解密
  19. byte[] decodeContent2 = decryptPrivateKey(encodeContent2,getPrivateKey(map));
  20. System.out.println("私钥解密后的数据:"+new String(decodeContent2));
  21. System.out.println("============ 分隔符 ===========");
  22. // 6.加签
  23. String sign = sign(content.getBytes(),getPrivateKey(map));
  24. System.out.println("加签后的数据:"+sign);
  25. // 7.验签
  26. boolean result = verify(content.getBytes(),getPublicKey(map),sign);
  27. System.out.println("验签结果:"+result);
  28. }

运行结果

  1. 公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChRJmN8gv7te/xvgo55KvYlEGDGoVbDWF0rG6jCgw3pw/zGa/4R
  2. GGmRwOcBbecSYNZZUlQaqYZkta7m3ti0Z3o8ZhbYYMbtWI3eWs9MbsioCDSIsg/Jf6CHHS3HhjjQboQkKs7Q/1emn
  3. E01Sa9kYApoGVEXAtSY4kuxNidVjklgwIDAQAB
  4. 私钥:MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKFEmY3yC/u17/G+Cjnkq9iUQYMahVsNYXSsbqMKD
  5. DenD/MZr/hEYaZHA5wFt5xJg1llSVBqphmS1rube2LRnejxmFthgxu1Yjd5az0xuyKgINIiyD8l/oIcdLceGONBuh
  6. CQqztD/V6acTTVJr2RgCmgZURcC1JjiS7E2J1WOSWDAgMBAAECgYBEoH278wH4dr8KH7YYVuBuRQDv+qw/SB1t2ic
  7. myJLUaAqYiBjjTK5FZTj6/0/YeUwlEb42M3xFq8AnjA3gypUoqXFpHaRDbfZFanryDUQFLQ/C9141exJkX7QmHS5t
  8. 99WRSnPbVoLzRVc4F8FBu76HEN4uzOVl9akkaQXqbbJ6EQJBAPJFAzLcBnSRsSHXZt5hB9hjanUiTBbMQ4H2YL4Om
  9. ouX7uQOnMfW2PuGAE0+WMq/V4AgfLu0/yIG8s3XEFjsXosCQQCqaF512kQOW+YjlTpCE3KpXcZ9U7t5+G33r4MmA1
  10. 7lML5miTwEC+wo0sHDVL2yG0/CPk1itLd7yW2FqGEgGWvpAkEAmwn3JhEQQIEL7jA+sIk/0AavFg7AysYlXYIiHv6
  11. RgEvWoTOIuYqQiUYT41rGz9jrUh94M1d8/nWb5IaA+6coSQJBAJc3Pnt+UF4dlr+EsMnp0BoTKQwVvYuitJLSoKKe
  12. 4xqmgo8iwKsmmU4wl9jp3duq+L/54Vnx29BxEktE+8ssQ+ECQFeZ0CzBdPWMs6Hmsujgn5qS/FOlbyu4qckU5lAqN
  13. 3DGxmtdvWne2NZYzCFCWT9zBlWd0dXKccmq+ehrBWrd+Fc=
  14. ============ 分隔符 ===========
  15. 私钥加密后的数据:!�h��^��0�IȕoBa�k(�/��ΜA��ǩ%��u�|
  16. �R�Z�l���y��<����$|
  17. ��!M�S��&n�u{���p�E5�WG�����=>�S��U���=��UT��W�Q�6�|D�{
  18. 公钥解密后的数据:未加密数据
  19. ============ 分隔符 ===========
  20. 公钥加密后的数据:}>d��J�)Ԙe_A�G ��kۈ���Js�����R=�����ax�v9���m�[z
  21. ��b�NT�cѓب_0�薹���UZ����
  22. IDJ|gI���.A��|�N�x�&$��k�t F
  23. 私钥解密后的数据:未加密数据
  24. ============ 分隔符 ===========
  25. 加签后的数据:ZMxyo9gBoPnauK1uZx8Pb+jH9jn0gIA5D5uWFmimb3S1HuMrWl6DnQuIgv/dwemHJREnkdE2F65sR0qxLNAr0REdW
  26. GakYPEj0UfbdMUzrduC2rxKIyX5jOTt3RpBIM1bK3sJISSmheK0Tb7msYTrA2VKscNM1gAHqIbnaMNeDwY=
  27. 验签结果:true

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/601124
推荐阅读
相关标签
  

闽ICP备14008679号