加密算法使用(五):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 }
原文地址:https://www.cnblogs.com/flying607/p/5442956.html