zl程序教程

您现在的位置是:首页 >  其他

当前栏目

RSA加密例子和中途遇到的问题

加密 遇到 例子 rsa 问题
2023-09-27 14:25:17 时间

在进行RSA加密例子

Java代码  收藏代码
  1. package test;  
  2. import java.io.IOException;  
  3. import java.security.Key;  
  4. import java.security.KeyFactory;  
  5. import java.security.KeyPair;  
  6. import java.security.KeyPairGenerator;  
  7. import java.security.PrivateKey;  
  8. import java.security.PublicKey;  
  9. import java.security.Signature;  
  10. import java.security.interfaces.RSAPrivateKey;  
  11. import java.security.interfaces.RSAPublicKey;  
  12. import java.security.spec.PKCS8EncodedKeySpec;  
  13. import java.security.spec.X509EncodedKeySpec;  
  14. import sun.misc.BASE64Decoder;   
  15. import sun.misc.BASE64Encoder;  
  16.   
  17. import java.util.HashMap;  
  18. import java.util.Map;  
  19.   
  20. import javax.crypto.Cipher;  
  21.   
  22. public abstract class RSACoder {  
  23.     public static final String KEY_ALGORITHM = "RSA";  
  24.     public static final String SIGNATURE_ALGORITHM = "MD5withRSA";  
  25.   
  26.     private static final String PUBLIC_KEY = "RSAPublicKey";  
  27.     private static final String PRIVATE_KEY = "RSAPrivateKey";  
  28.   
  29.       
  30.     public static byte[] decryptBASE64(String privateKey){  
  31.         byte[] output = null;  
  32.         try {  
  33.             output = (new BASE64Decoder()).decodeBuffer(privateKey);  
  34.             return  output;  
  35.         } catch (IOException e) {  
  36.             e.printStackTrace();  
  37.         }  
  38.         return output;    
  39.     }  
  40.       
  41.       
  42.     public static String encryptBASE64( byte[] keyBytes){  
  43.          String s = (new BASE64Encoder()).encode(keyBytes);  
  44.          return s;  
  45.     }  
  46.       
  47.     /** 
  48.      * 用私钥对信息生成数字签名 
  49.      *  
  50.      * @param data 
  51.      *            加密数据 
  52.      * @param privateKey 
  53.      *            私钥 
  54.      *  
  55.      * @return 
  56.      * @throws Exception 
  57.      */  
  58.     public static String sign(byte[] data, String privateKey) throws Exception {  
  59.         // 解密由base64编码的私钥  
  60.         byte[] keyBytes = decryptBASE64(privateKey);  
  61.   
  62.         // 构造PKCS8EncodedKeySpec对象  
  63.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
  64.   
  65.         // KEY_ALGORITHM 指定的加密算法  
  66.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  67.   
  68.         // 取私钥匙对象  
  69.         PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);  
  70.   
  71.         // 用私钥对信息生成数字签名  
  72.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  
  73.         signature.initSign(priKey);  
  74.         signature.update(data);  
  75.           
  76.         return encryptBASE64(signature.sign());  
  77.     }  
  78.   
  79.     /** 
  80.      * 校验数字签名 
  81.      *  
  82.      * @param data 
  83.      *            加密数据 
  84.      * @param publicKey 
  85.      *            公钥 
  86.      * @param sign 
  87.      *            数字签名 
  88.      *  
  89.      * @return 校验成功返回true 失败返回false 
  90.      * @throws Exception 
  91.      *  
  92.      */  
  93.     public static boolean verify(byte[] data, String publicKey, String sign)  
  94.             throws Exception {  
  95.   
  96.         // 解密由base64编码的公钥  
  97.         byte[] keyBytes = decryptBASE64(publicKey);  
  98.   
  99.         // 构造X509EncodedKeySpec对象  
  100.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  
  101.   
  102.         // KEY_ALGORITHM 指定的加密算法  
  103.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  104.   
  105.         // 取公钥匙对象  
  106.         PublicKey pubKey = keyFactory.generatePublic(keySpec);  
  107.   
  108.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  
  109.         signature.initVerify(pubKey);  
  110.         signature.update(data);  
  111.   
  112.         // 验证签名是否正常  
  113.         return signature.verify(decryptBASE64(sign));  
  114.     }  
  115.   
  116.     /** 
  117.      * 解密<br> 
  118.      * 用私钥解密 
  119.      *  
  120.      * @param data 
  121.      * @param key 
  122.      * @return 
  123.      * @throws Exception 
  124.      */  
  125.     public static byte[] decryptByPrivateKey(byte[] data, String key)  
  126.             throws Exception {  
  127.         // 对密钥解密  
  128.         byte[] keyBytes = decryptBASE64(key);  
  129.   
  130.         // 取得私钥  
  131.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
  132.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  133.         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);  
  134.   
  135.         // 对数据解密  
  136.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  137.         cipher.init(Cipher.DECRYPT_MODE, privateKey);  
  138.   
  139.         return cipher.doFinal(data);  
  140.     }  
  141.   
  142.     /** 
  143.      * 解密<br> 
  144.      * 用公钥解密 
  145.      *  
  146.      * @param data 
  147.      * @param key 
  148.      * @return 
  149.      * @throws Exception 
  150.      */  
  151.     public static byte[] decryptByPublicKey(byte[] data, String key)  
  152.             throws Exception {  
  153.         // 对密钥解密  
  154.         byte[] keyBytes = decryptBASE64(key);  
  155.   
  156.         // 取得公钥  
  157.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
  158.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  159.         Key publicKey = keyFactory.generatePublic(x509KeySpec);  
  160.   
  161.         // 对数据解密  
  162.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  163.         cipher.init(Cipher.DECRYPT_MODE, publicKey);  
  164.   
  165.         return cipher.doFinal(data);  
  166.     }  
  167.   
  168.     /** 
  169.      * 加密<br> 
  170.      * 用公钥加密 
  171.      *  
  172.      * @param data 
  173.      * @param key 
  174.      * @return 
  175.      * @throws Exception 
  176.      */  
  177.     public static byte[] encryptByPublicKey(byte[] data, String key)  
  178.             throws Exception {  
  179.         // 对公钥解密  
  180.         byte[] keyBytes = decryptBASE64(key);  
  181.   
  182.         // 取得公钥  
  183.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
  184.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  185.         Key publicKey = keyFactory.generatePublic(x509KeySpec);  
  186.   
  187.         // 对数据加密  
  188.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  189.         cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
  190.   
  191.         return cipher.doFinal(data);  
  192.     }  
  193.   
  194.     /** 
  195.      * 加密<br> 
  196.      * 用私钥加密 
  197.      *  
  198.      * @param data 
  199.      * @param key 
  200.      * @return 
  201.      * @throws Exception 
  202.      */  
  203.     public static byte[] encryptByPrivateKey(byte[] data, String key)  
  204.             throws Exception {  
  205.         // 对密钥解密  
  206.         byte[] keyBytes = decryptBASE64(key);  
  207.   
  208.         // 取得私钥  
  209.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
  210.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  211.         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);  
  212.   
  213.         // 对数据加密  
  214.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  215.         cipher.init(Cipher.ENCRYPT_MODE, privateKey);  
  216.   
  217.         return cipher.doFinal(data);  
  218.     }  
  219.   
  220.     /** 
  221.      * 取得私钥 
  222.      *  
  223.      * @param keyMap 
  224.      * @return 
  225.      * @throws Exception 
  226.      */  
  227.     public static String getPrivateKey(Map<String, Object> keyMap)  
  228.             throws Exception {  
  229.         Key key = (Key) keyMap.get(PRIVATE_KEY);  
  230.   
  231.         return encryptBASE64(key.getEncoded());  
  232.     }  
  233.   
  234.     /** 
  235.      * 取得公钥 
  236.      *  
  237.      * @param keyMap 
  238.      * @return 
  239.      * @throws Exception 
  240.      */  
  241.     public static String getPublicKey(Map<String, Object> keyMap)  
  242.             throws Exception {  
  243.         Key key = (Key) keyMap.get(PUBLIC_KEY);  
  244.   
  245.         return encryptBASE64(key.getEncoded());  
  246.     }  
  247.   
  248.     /** 
  249.      * 初始化密钥 
  250.      *  
  251.      * @return 
  252.      * @throws Exception 
  253.      */  
  254.     public static Map<String, Object> initKey() throws Exception {  
  255.         KeyPairGenerator keyPairGen = KeyPairGenerator  
  256.                 .getInstance(KEY_ALGORITHM);  
  257.         keyPairGen.initialize(1024);  
  258.   
  259.         KeyPair keyPair = keyPairGen.generateKeyPair();  
  260.   
  261.         // 公钥  
  262.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
  263.   
  264.         // 私钥  
  265.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
  266.   
  267.         Map<String, Object> keyMap = new HashMap<String, Object>(2);  
  268.   
  269.         keyMap.put(PUBLIC_KEY, publicKey);  
  270.         keyMap.put(PRIVATE_KEY, privateKey);  
  271.         return keyMap;  
  272.     }  
  273. }  




测试类

Java代码  收藏代码
  1. package test;  
  2. import java.util.Map;  
  3. import java.util.regex.Matcher;  
  4. import java.util.regex.Pattern;  
  5. import sun.misc.BASE64Decoder;   
  6. import sun.misc.BASE64Encoder;  
  7. public class RSACoderTest {  
  8.       
  9. package com;  
  10. import java.util.Map;  
  11. import sun.misc.BASE64Encoder;  
  12. public class RSACoderTest {  
  13.         static String privateKey ;  
  14.         static String publicKey ;  
  15.         public static void getKey() throws Exception {  
  16.         Map<String, Object> keyMap = RSACoder.initKey();  
  17.   
  18.         publicKey = RSACoder.getPublicKey(keyMap);  
  19.         privateKey = RSACoder.getPrivateKey(keyMap);  
  20.         //公钥生成  
  21.         System.out.println("public : "+publicKey);  
  22.         //私钥生成  
  23.         System.out.println("private : "+privateKey);  
  24.     }  
  25.     public static void main(String[] args) throws Exception {  
  26.          getKey() ;  
  27. //      System.err.println("公钥加密——私钥解密");  
  28.                 //将明文转换为字节数组  
  29.         byte[] data = "serricee1".getBytes();  
  30.                //用公钥加密  
  31.         byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);  
  32.                 //打印加密字符串 为什么使用BASE64Encoder 因为在RSACoder里加密用的是 BASE64Encoder 加密  
  33.         String s = (new BASE64Encoder()).encode(encodedData);    
  34.         System.err.println("加密: " +s);  
  35. //                //用私钥解密  
  36.         byte[] decodedData = RSACoder.decryptByPrivateKey(RSACoder.decryptBASE64(s),privateKey);  
  37. //  
  38. //        
  39.         System.out.println( "解密后: " + new String(decodedData));  
  40.     }  
  41.       
  42.   
  43. }  



遇到的问题在
解密的时候 用new BASE64Encoder()).encode(keyBytes); 获得明文发现明文长度只能是4的倍数而且不支持特殊字符串和中文不然解密出来不是多出来 就是解密不对 后面解密
直接用.getBytes() 和new String(decodedData)不用Base64的就好了