zoukankan      html  css  js  c++  java
  • RSA加密例子和中途遇到的问题

    在进行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的就好了

  • 相关阅读:
    Docker++:Docker根据名称查询容器ID镜像ID并停止删除
    Jenkins++:Jenkins 部署 war 包到 tomcat8,报错
    Vue++:不同环境打包方式
    Linux++:实现SSH无密码登录
    Jenkins++:Job for jenkins.service failed because the control process exited with error code. See "systemctl st
    Linux++:常用依赖安装
    哈希法学习
    nodeJS笔记
    链表之环形链表
    双指针法数组三数之和
  • 原文地址:https://www.cnblogs.com/kabi/p/6255940.html
Copyright © 2011-2022 走看看