使用非对称算法RSA实现加解密和使用签名算法SHA1WithRSA、MD5withRSA生成签名以及验签

不啰嗦,直接上源码

  1 package com.hudai.platform.manager.util;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.IOException;
  5 import java.io.StringWriter;
  6 import java.io.UnsupportedEncodingException;
  7 import java.security.Key;
  8 import java.security.KeyFactory;
  9 import java.security.KeyPair;
 10 import java.security.KeyPairGenerator;
 11 import java.security.NoSuchAlgorithmException;
 12 import java.security.PrivateKey;
 13 import java.security.PublicKey;
 14 import java.security.interfaces.RSAPrivateKey;
 15 import java.security.interfaces.RSAPublicKey;
 16 import java.security.spec.InvalidKeySpecException;
 17 import java.security.spec.PKCS8EncodedKeySpec;
 18 import java.security.spec.X509EncodedKeySpec;
 19 import java.util.HashMap;
 20 import java.util.Map;
 21 
 22 import javax.crypto.Cipher;
 23 
 24 import org.apache.commons.codec.binary.Base64;
 25 import org.apache.tomcat.util.http.fileupload.IOUtils;
 26 import org.bouncycastle.asn1.ASN1Encodable;
 27 import org.bouncycastle.asn1.ASN1Primitive;
 28 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
 29 import org.bouncycastle.util.io.pem.PemObject;
 30 import org.bouncycastle.util.io.pem.PemWriter;
 31 import org.slf4j.Logger;
 32 import org.slf4j.LoggerFactory;
 33 
 34 /**
 35  * @author WanHongLei
 36  * @version 创建时间:2019年2月13日 上午10:27:06 类说明
 37  */
 38 public class RSAUtils {
 39     /**
 40      * 字符串编码
 41      */
 42     public static final String CHARSET = "UTF-8";
 43     /**
 44      * 加密算法RSA
 45      */
 46     public static final String RSA_ALGORITHM = "RSA";
 47     /**
 48      * 签名算法
 49      */
 50     public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";// SHA1WithRSA MD5withRSA
 51     
 52     private static final Logger logger = LoggerFactory.getLogger(RSAUtils.class);
 53 
 54     /**
 55      * 创建公钥私钥
 56      * 
 57      * @param keySize
 58      *            1024 2048
 59      * @return
 60      */
 61     public static Map createKeys(int keySize) {
 62         // 为RSA算法创建一个KeyPairGenerator对象
 63         KeyPairGenerator kpg;
 64         try {
 65             kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
 66         } catch (NoSuchAlgorithmException e) {
 67             throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
 68         }
 69 
 70         // 初始化KeyPairGenerator对象,密钥长度
 71         kpg.initialize(keySize);
 72         // 生成密匙对
 73         KeyPair keyPair = kpg.generateKeyPair();
 74         // 得到公钥
 75         Key publicKey = keyPair.getPublic();
 76         String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
 77         // 得到私钥
 78         Key privateKey = keyPair.getPrivate();
 79         String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
 80         
 81         
 82         Map keyPairMap = new HashMap();
 83         keyPairMap.put("publicKey", publicKeyStr);
 84         keyPairMap.put("privateKeyOfPKCS8", privateKeyStr);
 85         keyPairMap.put("privateKeyOfPKCS1", getPrivateKeyOfPKCS1(privateKeyStr));
 86 
 87         return keyPairMap;
 88     }
 89 
 90     /**
 91      * 得到公钥
 92      * 
 93      * @param publicKey
 94      *            密钥字符串(经过base64编码)
 95      * @throws Exception
 96      */
 97     public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
 98         // 通过X509编码的Key指令获得公钥对象
 99         KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
100         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
101         RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
102         return key;
103     }
104 
105     /**
106      * 得到私钥pkcs8
107      * 
108      * @param privateKey
109      *            密钥字符串(经过base64编码)
110      * @throws Exception
111      */
112     public static RSAPrivateKey getPrivateKey(String privateKey)
113             throws NoSuchAlgorithmException, InvalidKeySpecException {
114         // 通过PKCS#8编码的Key指令获得私钥对象
115         KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
116         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
117         RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
118         return key;
119     }
120     
121     
122     public static String getPrivateKeyOfPKCS1(String privateKey){
123         try {
124             byte[] privBytes = Base64.decodeBase64(privateKey);
125 
126             PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privBytes);
127             ASN1Encodable encodable = pkInfo.parsePrivateKey();
128             ASN1Primitive primitive = encodable.toASN1Primitive();
129             byte[] privateKeyPKCS1 = primitive.getEncoded();
130 
131             return pkcs1ToPem(privateKeyPKCS1,false);
132         } catch (IOException e) {
133             logger.error("PKCS8ToPKCS1 error", e);
134             return null;
135         } catch (Exception e) {
136             logger.error("PKCS8ToPKCS1 error", e);
137             return null;
138         }
139     }
140 
141     public static String pkcs1ToPem(byte[] pcks1KeyBytes,boolean isPublic) throws Exception{
142         String type;
143         if(isPublic){
144             type = "RSA PUBLIC KEY";
145         }else{
146             type = "RSA PRIVATE KEY";
147         }
148 
149         PemObject pemObject = new PemObject(type, pcks1KeyBytes);
150         StringWriter stringWriter = new StringWriter();
151         PemWriter pemWriter = new PemWriter(stringWriter);
152         pemWriter.writeObject(pemObject);
153         pemWriter.close();
154         String pemString = stringWriter.toString();
155 
156         return pemString;
157     }
158 
159     /**
160      * 公钥加密
161      * 
162      * @param data
163      * @param publicKey
164      * @return
165      */
166     public static String publicEncrypt(String data, RSAPublicKey publicKey) {
167         try {
168             Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
169             cipher.init(Cipher.ENCRYPT_MODE, publicKey);
170             return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),
171                     publicKey.getModulus().bitLength()));
172         } catch (Exception e) {
173             throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
174         }
175     }
176 
177     /**
178      * 私钥解密
179      * 
180      * @param data
181      * @param privateKey
182      * @return
183      */
184 
185     public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
186         try {
187             Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
188             cipher.init(Cipher.DECRYPT_MODE, privateKey);
189             return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),
190                     privateKey.getModulus().bitLength()), CHARSET);
191         } catch (Exception e) {
192             throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
193         }
194     }
195 
196     /**
197      * 私钥加密
198      * 
199      * @param data
200      * @param privateKey
201      * @return
202      */
203 
204     public static String privateEncrypt(String data, RSAPrivateKey privateKey) {
205         try {
206             Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
207             cipher.init(Cipher.ENCRYPT_MODE, privateKey);
208             return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),
209                     privateKey.getModulus().bitLength()));
210         } catch (Exception e) {
211             throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
212         }
213     }
214 
215     /**
216      * 公钥解密
217      * 
218      * @param data
219      * @param publicKey
220      * @return
221      */
222 
223     public static String publicDecrypt(String data, RSAPublicKey publicKey) {
224         try {
225             Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
226             cipher.init(Cipher.DECRYPT_MODE, publicKey);
227             return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),
228                     publicKey.getModulus().bitLength()), CHARSET);
229         } catch (Exception e) {
230             throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
231         }
232     }
233 
234     /**
235      * 分段处理
236      * 
237      * @param cipher
238      * @param opmode
239      * @param datas
240      * @param keySize
241      * @return
242      */
243     private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
244         int maxBlock = 0;
245         if (opmode == Cipher.DECRYPT_MODE) {
246             maxBlock = keySize / 8;
247         } else {
248             maxBlock = keySize / 8 - 11;
249         }
250         ByteArrayOutputStream out = new ByteArrayOutputStream();
251         int offSet = 0;
252         byte[] buff;
253         int i = 0;
254         try {
255             while (datas.length > offSet) {
256                 if (datas.length - offSet > maxBlock) {
257                     buff = cipher.doFinal(datas, offSet, maxBlock);
258                 } else {
259                     buff = cipher.doFinal(datas, offSet, datas.length - offSet);
260                 }
261                 out.write(buff, 0, buff.length);
262                 i++;
263                 offSet = i * maxBlock;
264             }
265         } catch (Exception e) {
266             throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
267         }
268         byte[] resultDatas = out.toByteArray();
269         IOUtils.closeQuietly(out);
270         return resultDatas;
271     }
272 
273     /**
274      * RSA签名
275      * 
276      * @param content
277      *            待签名数据
278      * @param privateKey
279      *            商户私钥
280      * @param encode
281      *            字符集编码
282      * @return 签名值
283      */
284     public static String sign(String content, String privateKey, String encode) {
285         try {
286             PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
287 
288             KeyFactory keyf = KeyFactory.getInstance(RSA_ALGORITHM);
289             PrivateKey priKey = keyf.generatePrivate(priPKCS8);
290 
291             java.security.Signature signature = java.security.Signature.getInstance(SIGNATURE_ALGORITHM);
292 
293             signature.initSign(priKey);
294             signature.update(content.getBytes(encode));
295 
296             byte[] signed = signature.sign();
297 
298             return Base64.encodeBase64URLSafeString(signed);
299         } catch (Exception e) {
300             throw new RuntimeException("签名发生异常", e);
301         }
302     }
303 
304     /**
305      * RSA验签名检查
306      * 
307      * @param content  待签名数据
308      * @param sign 签名值
309      * @param publicKey 分配给开发商公钥
310      * @param encode 字符集编码
311      * @return 布尔值
312      */
313     public static boolean verify(String content, String sign, String publicKey, String encode) {
314         try {
315             KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
316             byte[] encodedKey = Base64.decodeBase64(publicKey);
317             PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
318 
319             java.security.Signature signature = java.security.Signature.getInstance(SIGNATURE_ALGORITHM);
320 
321             signature.initVerify(pubKey);
322             signature.update(content.getBytes(encode));
323 
324             boolean bverify = signature.verify(Base64.decodeBase64(sign));
325             return bverify;
326 
327         } catch (Exception e) {
328             e.printStackTrace();
329         }
330 
331         return false;
332     }
333 
334     public static void main(String[] args) throws UnsupportedEncodingException, Exception {
335         Map keyMap = createKeys(2048);
336         String publicKey = keyMap.get("publicKey");
337         String privateKeyOfPKCS8 = keyMap.get("privateKeyOfPKCS8");
338         String privateKeyOfPKCS1 = keyMap.get("privateKeyOfPKCS1");
339         
340         System.out.println("publicKey:\n" + publicKey);
341         System.out.println("privateKeyOfPKCS8:\n" + privateKeyOfPKCS8);
342         System.out.println("privateKeyOfPKCS1:\n" + privateKeyOfPKCS1);
343         
344         String src = "app_id=35456878542&biz_data={\"order_no\":\"201811307810149579\",\"order_status\":100,\"update_time\":1543566391}&format=json&method=api.v2.order.orderfeedback&sign_type=RSA×tamp=1543566391&version=1.0";
345         
346         String sign = sign(src, privateKeyOfPKCS8, CHARSET);
347         System.out.println("sign:\n" + sign);
348         
349         boolean verify = verify(src, sign, publicKey, CHARSET);
350         System.out.println("verify:" + verify);
351         
352         String privateEncrypt = privateEncrypt(src, getPrivateKey(privateKeyOfPKCS8));
353         System.out.println("privateEncrypt:\n" + privateEncrypt);
354         
355         String publicDecrypt = publicDecrypt(privateEncrypt, getPublicKey(publicKey));
356         System.out.println("publicDecrypt:\n" + publicDecrypt);
357         
358         String publicEncrypt = publicEncrypt(src, getPublicKey(publicKey));
359         System.out.println("publicEncrypt:\n" + publicEncrypt);
360         
361         String privateDecrypt = privateDecrypt(publicEncrypt, getPrivateKey(privateKeyOfPKCS8));
362         System.out.println("privateDecrypt:\n" + privateDecrypt);
363         
364     }
365 }

 

你可能感兴趣的:(使用非对称算法RSA实现加解密和使用签名算法SHA1WithRSA、MD5withRSA生成签名以及验签)