• 加密算法使用(五):RSA使用全过程


    RSA是一种非对称加密算法,使用RSA前先生成一对公钥和私钥。

    使用公钥加密的数据可以用私钥解密,同样私钥加密的数据也可以用公钥解密,

    不同之处在于,私钥加密数据的同时还可以生成一组签名,签名是用来验证数据是否在传输过程中有变动的,使用公钥、签名、以及公钥加密后的数据,就可以验证是否有变动,当然也可以不验证。

    代码示例如下,两个main方法:main和main1。加密解密都是针对byte数组的,考虑到我们实际使用的时候大部分场景应该是用字符串来传递数据,所以演示代码中频繁的将byte数组转化为字符串,有些byte数组不是从字符串直接转化来的,直接通过new String的方式转字符串会出现乱码,所以用到了Base64来解决这一问题。

    另外,演示代码为了方便看到全过程,基本上没有抽出方法,实际使用的时候建议重构一下。

    说明就到此为止,代码如下:

      1 package testEncrypt;
      2 
      3 import java.security.Key;
      4 import java.security.KeyFactory;
      5 import java.security.KeyPair;
      6 import java.security.KeyPairGenerator;
      7 import java.security.NoSuchAlgorithmException;
      8 import java.security.PrivateKey;
      9 import java.security.PublicKey;
     10 import java.security.Signature;
     11 import java.security.interfaces.RSAPrivateKey;
     12 import java.security.interfaces.RSAPublicKey;
     13 import java.security.spec.InvalidKeySpecException;
     14 import java.security.spec.PKCS8EncodedKeySpec;
     15 import java.security.spec.X509EncodedKeySpec;
     16 import java.util.HashMap;
     17 import java.util.Map;
     18 
     19 import javax.crypto.Cipher;
     20 
     21 import org.apache.commons.codec.binary.Base64;
     22 
     23 /**
     24  * 
     25  * @ClassName: TestRsaEncrypt
     26  * @Description: TODO
     27  * @author: liuyx
     28  * @date: 2016年4月28日上午10:20:59
     29  */
     30 public class TestRsaEncrypt {
     31     public static final String KEY_ALGORITHM = "RSA";  
     32     private static final String PUBLIC_KEY = "RSAPublicKey";  
     33     private static final String PRIVATE_KEY = "RSAPrivateKey";  
     34     public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
     35     private static KeyFactory keyFactory = null;
     36     static {
     37         try {
     38             keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
     39         } catch (NoSuchAlgorithmException e) {
     40             // TODO Auto-generated catch block
     41             e.printStackTrace();
     42         }
     43     }
     44     //公钥加密 私钥解密
     45     public static void main(String[] args) throws Exception {
     46         //生成密钥对
     47         
     48         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);  
     49         keyPairGen.initialize(512);  
     50   
     51         KeyPair keyPair = keyPairGen.generateKeyPair();  
     52   
     53         // 公钥  
     54         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
     55   
     56         // 私钥  
     57         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
     58   
     59         Map<String, Object> keyMap = new HashMap<String, Object>(2);  
     60   
     61         keyMap.put(PUBLIC_KEY, publicKey);  
     62         keyMap.put(PRIVATE_KEY, privateKey); 
     63         
     64         String publicKeyStr = getBase64KeyEncodeStrFromKey(publicKey);
     65         String privateKeyStr = getBase64KeyEncodeStrFromKey(privateKey);
     66         System.out.println("公钥:"+publicKeyStr);
     67         System.out.println("私钥:"+privateKeyStr);
     68         
     69         //数据加密过程演示
     70         System.out.println("公钥加密——私钥解密");  
     71         
     72         //要加密的数据
     73         String dataStr = "abcdefghhhhhhhopqrst";
     74         System.out.println("要加密的数据:"+dataStr);
     75         byte[] data = dataStr.getBytes();
     76         
     77         
     78         // 对公钥解密  
     79         Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr);  
     80   
     81         // 对数据加密  
     82         Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);  
     83         cipher.init(Cipher.ENCRYPT_MODE, decodePublicKey);  
     84         byte[] encodedData = cipher.doFinal(data); 
     85         String encodedDataStr = Base64.encodeBase64String(encodedData);
     86         System.out.println("公钥加密后的数据:"+encodedDataStr);
     87         
     88         //对私钥解密
     89         Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKeyStr);
     90         cipher.init(Cipher.DECRYPT_MODE, decodePrivateKey); 
     91         encodedData = Base64.decodeBase64(encodedDataStr);
     92         byte[] decodedData = cipher.doFinal(encodedData); 
     93         String decodedDataStr = new String(decodedData);
     94         System.out.println("私钥解密后的数据:"+decodedDataStr);
     95     }
     96     
     97     //私钥加密 公钥解密,附带签名验证过程
     98     public static void main1(String[] args) throws Exception {
     99         //生成密钥对
    100         
    101         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);  
    102         keyPairGen.initialize(512);  
    103   
    104         KeyPair keyPair = keyPairGen.generateKeyPair();  
    105   
    106         // 公钥  
    107         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
    108   
    109         // 私钥  
    110         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
    111   
    112         Map<String, Object> keyMap = new HashMap<String, Object>(2);  
    113   
    114         keyMap.put(PUBLIC_KEY, publicKey);  
    115         keyMap.put(PRIVATE_KEY, privateKey); 
    116         
    117         String publicKeyStr = getBase64KeyEncodeStrFromKey(publicKey);
    118         String privateKeyStr = getBase64KeyEncodeStrFromKey(privateKey);
    119         System.out.println("公钥:"+publicKeyStr);
    120         System.out.println("私钥:"+privateKeyStr);
    121         
    122         //数据加密过程演示
    123         System.out.println("私钥加密——公钥解密");  
    124         
    125         //要加密的数据
    126         String dataStr = "abcdefghhhhhhhopqrst1";
    127         System.out.println("要加密的数据:"+dataStr);
    128         byte[] data = dataStr.getBytes();
    129         
    130         //对私钥解密
    131         Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKeyStr);
    132         //对公钥解密  
    133         Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr);  
    134   
    135         // 对数据加密  
    136         Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);  
    137         cipher.init(Cipher.ENCRYPT_MODE, decodePrivateKey);  
    138         byte[] encodedData = cipher.doFinal(data); 
    139         
    140         //插曲,加密后的数据+私钥,生成签名,验证签名
    141         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  
    142         signature.initSign((PrivateKey)decodePrivateKey);  //用的是私钥
    143         signature.update(encodedData);  //用的是加密后的数据字节数组
    144   
    145         //取得签名
    146         String sign = Base64.encodeBase64String((signature.sign())); 
    147         
    148         //初始化验证签名
    149         signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    150         signature.initVerify((PublicKey )decodePublicKey);  //用的是公钥
    151         signature.update(encodedData);  //用的是加密后的数据字节数组
    152         
    153         //实际的验证过程,获取验证结果
    154         boolean ret = signature.verify(Base64.decodeBase64(sign));
    155         System.out.println("验证结果:"+ret);
    156         //插曲结束
    157         
    158         
    159         String encodedDataStr = Base64.encodeBase64String(encodedData);
    160         System.out.println("私钥加密后的数据:"+encodedDataStr);
    161         
    162         
    163         
    164         cipher.init(Cipher.DECRYPT_MODE, decodePublicKey); 
    165         encodedData = Base64.decodeBase64(encodedDataStr);
    166         byte[] decodedData = cipher.doFinal(encodedData); 
    167         String decodedDataStr = new String(decodedData);
    168         System.out.println("公钥解密后的数据:"+decodedDataStr);
    169         
    170     }
    171     
    172     /*
    173      * 获取key的base64加密后的字符串
    174      */
    175     private static String getBase64KeyEncodeStrFromKey(Key key) {
    176         return Base64.encodeBase64String(key.getEncoded());
    177     }
    178     
    179     /*
    180      * 获取base64加密后的字符串的原始公钥
    181      */
    182     private static Key getPublicKeyFromBase64KeyEncodeStr(String keyStr) {
    183         byte[] keyBytes = Base64.decodeBase64(keyStr);  
    184         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
    185         Key publicKey = null;
    186         try {
    187             publicKey = keyFactory.generatePublic(x509KeySpec);  
    188         } catch (Exception e) {
    189             // TODO Auto-generated catch block
    190             e.printStackTrace();
    191         }  
    192         return publicKey;
    193     }
    194     
    195     private static Key getPrivateKeyFromBase64KeyEncodeStr(String keyStr) {
    196         byte[] keyBytes = Base64.decodeBase64(keyStr); 
    197         // 取得私钥  
    198         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
    199 
    200         Key privateKey=null;
    201         try {
    202             privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    203         } catch (InvalidKeySpecException e) {
    204             // TODO Auto-generated catch block
    205             e.printStackTrace();
    206         }  
    207         return privateKey;
    208     }
    209 }
  • 相关阅读:
    致 CODING 用户的元宵问候
    持续集成之理论篇
    基于 CODING 的 Spring Boot 持续集成项目
    使用 CODING 进行 Hexo 项目的持续集成
    使用 CODING 进行 Spring Boot 项目的集成
    三种前端模块化规范
    XSS和CSRF
    小问题填坑,关于obj.x和obj["x"]
    说一个闭包在实际开发中的应用
    关于return的分号自动插入问题
  • 原文地址:https://www.cnblogs.com/flying607/p/5442956.html
Copyright © 2020-2023  润新知