不啰嗦,直接上源码
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 MapcreateKeys(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 }