|
|
@@ -0,0 +1,326 @@
|
|
|
+package com.xunmei.common.core.utils;
|
|
|
+
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
+
|
|
|
+import javax.crypto.BadPaddingException;
|
|
|
+import javax.crypto.Cipher;
|
|
|
+import javax.crypto.IllegalBlockSizeException;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.security.*;
|
|
|
+import java.security.interfaces.RSAPrivateKey;
|
|
|
+import java.security.interfaces.RSAPublicKey;
|
|
|
+import java.security.spec.InvalidKeySpecException;
|
|
|
+import java.security.spec.PKCS8EncodedKeySpec;
|
|
|
+import java.security.spec.X509EncodedKeySpec;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author hms
|
|
|
+ */
|
|
|
+public class RsaHelper {
|
|
|
+
|
|
|
+ public static String publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyJdVXw+TvnFnE2ElRmJflkFO20wSjJzS+XV887at9jTKa+EhpSg7aCNgCcFQfCEVpHVKegR4s02+4RH4q+y0gP/yIjAdyKAh16gC9NiM83WpN/PfBCOon55bIJI5G0OBi1I0el+3rpBqtRRzlRfiOXi4C6pmO0ayVmP5rVNASsQIDAQAB";
|
|
|
+
|
|
|
+ public static String privateKeyString = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALIl1VfD5O+cWcTYSVGYl+WQU7bTBKMnNL5dXzztq32NMpr4SGlKDtoI2AJwVB8IRWkdUp6BHizTb7hEfir7LSA//IiMB3IoCHXqAL02Izzdak3898EI6ifnlsgkjkbQ4GLUjR6X7eukGq1FHOVF+I5eLgLqmY7RrJWY/mtU0BKxAgMBAAECgYB5cn1c1blO+GHiZiilrcdvwtKvQnBY4bN9S55PpR9R+l5Tc4u567jwPzMzhmxys2rOXCUk1ZVCrentzxPMLWv2+zHo+DdlgszpQcVSgFyPV+wFDcPxLcFRt3VXJG7wWtzs0iX1IjAa36X8vhwTDgxAXbiuNeDH2L7716inh+8IAQJBANj8MX84KRE3WVV2hTvx/rwTwtkFugzl3wBKjqCx1vZoLs2LgEriRTPUtDSg8gpi3LN4QbgsTK903v4eL1NfO0ECQQDSLfXhwNMnyU6k48OJS8YWFpS15yWD2L2a/hO158zuTJDy1SiV1LekH7fJ96y4VBKsjIuzFH4SLj6AuMtjEytxAkBPROK4PUYTegryw9esrJ2JDBcUvZjYeWnca2BrqEyFvE3M3XfC46KwarZiu6Fw1ekWz4oCxHxHZQTKBTD43kOBAkB6UP0TkKBSOzllhJe7QznYiPOqmQagIHbXyJ2381q0JCMG7z5bVBw7i6nuBBGkhGkJuhFi+r4T3o3JY8IZuoJBAkAMSruTTxnoAAuhwNKfGBSSyQ99KD1qIHhIPnqtfx9UhaR6diDBSMNknRP9PK6ZW9xy90CJ3jq4/zalIjAVqzUX";
|
|
|
+
|
|
|
+
|
|
|
+ public static String subDecodeStr(String str) throws Exception {
|
|
|
+ String[] strs = str.split(",");
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ for (int i = 0; i < strs.length; i++) {
|
|
|
+ sb.append(decodeStr(strs[i]));
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String encodeStr(String content) {
|
|
|
+ int keySize = 1024;
|
|
|
+ RsaHelper rsa = new RsaHelper();
|
|
|
+ KeyPairInfo info = rsa.getKeyPair(keySize); //每次调用的公钥 私钥都一样
|
|
|
+ int enSegmentSize = 117;//keysize=1024时,分段不能大于117 ;keysize>=2048时,分段不能大于keySize/8+128;
|
|
|
+ String ciphertext = rsa.encipher(content, info.getPublicKey(), enSegmentSize);
|
|
|
+ return ciphertext;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String decodeStr(String content) throws Exception {
|
|
|
+ int keySize = 1024;
|
|
|
+ RsaHelper rsa = new RsaHelper();
|
|
|
+ KeyPairInfo info = rsa.getKeyPair(keySize); //每次调用的公钥 私钥都一样
|
|
|
+ int deSegmentSize = 128;//等于keySize/8
|
|
|
+ String deTxt = rsa.decipher(content, info.getPrivateKey(), deSegmentSize);
|
|
|
+ return deTxt;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成公钥、私钥对(keysize=1024)
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public KeyPairInfo getKeyPair() {
|
|
|
+ return getKeyPair(1024);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成公钥、私钥对
|
|
|
+ *
|
|
|
+ * @param keySize
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public KeyPairInfo getKeyPair(int keySize) {
|
|
|
+ try {
|
|
|
+ KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
|
|
|
+ // 初始化密钥对生成器,密钥大小一般要大于1024位,
|
|
|
+// String aa=String.valueOf(new Random().nextInt(999999999));
|
|
|
+// SecureRandom random = new SecureRandom(aa.getBytes()); //?????
|
|
|
+// keyPairGen.initialize(keySize,random);
|
|
|
+ keyPairGen.initialize(keySize);
|
|
|
+ // 生成一个密钥对,保存在keyPair中
|
|
|
+ KeyPair keyPair = keyPairGen.generateKeyPair();
|
|
|
+ // 得到私钥
|
|
|
+ RSAPrivateKey oraprivateKey = (RSAPrivateKey) keyPair.getPrivate();
|
|
|
+ // 得到公钥
|
|
|
+ RSAPublicKey orapublicKey = (RSAPublicKey) keyPair.getPublic();
|
|
|
+
|
|
|
+ KeyPairInfo pairInfo = new KeyPairInfo(keySize);
|
|
|
+ //公钥
|
|
|
+ byte[] publicKeybyte = orapublicKey.getEncoded();
|
|
|
+// String publicKeyString = Base64.encodeBase64String(publicKeybyte);
|
|
|
+ pairInfo.setPublicKey(publicKeyString);
|
|
|
+ //私钥
|
|
|
+ byte[] privateKeybyte = oraprivateKey.getEncoded();
|
|
|
+// String privateKeyString = Base64.encodeBase64String(privateKeybyte);
|
|
|
+ pairInfo.setPrivateKey(privateKeyString);
|
|
|
+
|
|
|
+ return pairInfo;
|
|
|
+ } catch (Exception e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取公钥对象
|
|
|
+ *
|
|
|
+ * @param publicKeyBase64
|
|
|
+ * @return
|
|
|
+ * @throws InvalidKeySpecException
|
|
|
+ * @throws NoSuchAlgorithmException
|
|
|
+ */
|
|
|
+ public PublicKey getPublicKey(String publicKeyBase64)
|
|
|
+ throws InvalidKeySpecException, NoSuchAlgorithmException {
|
|
|
+
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
|
+ X509EncodedKeySpec publicpkcs8KeySpec =
|
|
|
+ new X509EncodedKeySpec(Base64.decodeBase64(publicKeyBase64));
|
|
|
+ PublicKey publicKey = keyFactory.generatePublic(publicpkcs8KeySpec);
|
|
|
+ return publicKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取私钥对象
|
|
|
+ *
|
|
|
+ * @param privateKeyBase64
|
|
|
+ * @return
|
|
|
+ * @throws NoSuchAlgorithmException
|
|
|
+ * @throws InvalidKeySpecException
|
|
|
+ */
|
|
|
+ public PrivateKey getPrivateKey(String privateKeyBase64)
|
|
|
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
|
+ PKCS8EncodedKeySpec privatekcs8KeySpec =
|
|
|
+ new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyBase64));
|
|
|
+ PrivateKey privateKey = keyFactory.generatePrivate(privatekcs8KeySpec);
|
|
|
+ return privateKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用共钥加密
|
|
|
+ *
|
|
|
+ * @param content 待加密内容
|
|
|
+ * @param publicKeyBase64 公钥 base64 编码
|
|
|
+ * @return 经过 base64 编码后的字符串
|
|
|
+ */
|
|
|
+ public String encipher(String content, String publicKeyBase64) {
|
|
|
+ return encipher(content, publicKeyBase64, -1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用共钥加密(分段加密)
|
|
|
+ *
|
|
|
+ * @param content 待加密内容
|
|
|
+ * @param publicKeyBase64 公钥 base64 编码
|
|
|
+ * @param segmentSize 分段大小,一般小于 keySize/8(段小于等于0时,将不使用分段加密)
|
|
|
+ * @return 经过 base64 编码后的字符串
|
|
|
+ */
|
|
|
+ public String encipher(String content, String publicKeyBase64, int segmentSize) {
|
|
|
+ try {
|
|
|
+ PublicKey publicKey = getPublicKey(publicKeyBase64);
|
|
|
+ return encipher(content, publicKey, segmentSize);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分段加密
|
|
|
+ *
|
|
|
+ * @param ciphertext 密文
|
|
|
+ * @param key 加密秘钥
|
|
|
+ * @param segmentSize 分段大小,<=0 不分段
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String encipher(String ciphertext, Key key, int segmentSize) {
|
|
|
+ try {
|
|
|
+ // 用公钥加密
|
|
|
+ byte[] srcBytes = ciphertext.getBytes();
|
|
|
+
|
|
|
+ // Cipher负责完成加密或解密工作,基于RSA
|
|
|
+ Cipher cipher = Cipher.getInstance("RSA");
|
|
|
+ // 根据公钥,对Cipher对象进行初始化
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, key);
|
|
|
+ byte[] resultBytes = null;
|
|
|
+
|
|
|
+ if (segmentSize > 0)
|
|
|
+ resultBytes = cipherDoFinal(cipher, srcBytes, segmentSize); //分段加密
|
|
|
+ else
|
|
|
+ resultBytes = cipher.doFinal(srcBytes);
|
|
|
+
|
|
|
+ String base64Str = Base64.encodeBase64String(resultBytes);
|
|
|
+ return base64Str;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分段大小
|
|
|
+ *
|
|
|
+ * @param cipher
|
|
|
+ * @param srcBytes
|
|
|
+ * @param segmentSize
|
|
|
+ * @return
|
|
|
+ * @throws IllegalBlockSizeException
|
|
|
+ * @throws BadPaddingException
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ private byte[] cipherDoFinal(Cipher cipher, byte[] srcBytes, int segmentSize)
|
|
|
+ throws IllegalBlockSizeException, BadPaddingException, IOException {
|
|
|
+ if (segmentSize <= 0)
|
|
|
+ throw new RuntimeException("分段大小必须大于0");
|
|
|
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
+ int inputLen = srcBytes.length;
|
|
|
+ int offSet = 0;
|
|
|
+ byte[] cache;
|
|
|
+ int i = 0;
|
|
|
+ // 对数据分段解密
|
|
|
+ while (inputLen - offSet > 0) {
|
|
|
+ if (inputLen - offSet > segmentSize) {
|
|
|
+ cache = cipher.doFinal(srcBytes, offSet, segmentSize);
|
|
|
+ } else {
|
|
|
+ cache = cipher.doFinal(srcBytes, offSet, inputLen - offSet);
|
|
|
+ }
|
|
|
+ out.write(cache, 0, cache.length);
|
|
|
+ i++;
|
|
|
+ offSet = i * segmentSize;
|
|
|
+ }
|
|
|
+ byte[] data = out.toByteArray();
|
|
|
+ out.close();
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用私钥解密
|
|
|
+ *
|
|
|
+ * @param contentBase64 待加密内容,base64 编码
|
|
|
+ * @param privateKeyBase64 私钥 base64 编码
|
|
|
+ * @return
|
|
|
+ * @segmentSize 分段大小
|
|
|
+ */
|
|
|
+ public String decipher(String contentBase64, String privateKeyBase64) throws Exception {
|
|
|
+ return decipher(contentBase64, privateKeyBase64, -1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用私钥解密(分段解密)
|
|
|
+ *
|
|
|
+ * @param contentBase64 待加密内容,base64 编码
|
|
|
+ * @param privateKeyBase64 私钥 base64 编码
|
|
|
+ * @return
|
|
|
+ * @segmentSize 分段大小
|
|
|
+ */
|
|
|
+ public String decipher(String contentBase64, String privateKeyBase64, int segmentSize) throws Exception {
|
|
|
+ PrivateKey privateKey = getPrivateKey(privateKeyBase64);
|
|
|
+ return decipher(contentBase64, privateKey, segmentSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分段解密
|
|
|
+ *
|
|
|
+ * @param contentBase64 密文
|
|
|
+ * @param key 解密秘钥
|
|
|
+ * @param segmentSize 分段大小(小于等于0不分段)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String decipher(String contentBase64, Key key, int segmentSize) throws Exception {
|
|
|
+ // 用私钥解密
|
|
|
+ byte[] srcBytes = Base64.decodeBase64(contentBase64);
|
|
|
+ // Cipher负责完成加密或解密工作,基于RSA
|
|
|
+ Cipher deCipher = Cipher.getInstance("RSA");
|
|
|
+ // 根据公钥,对Cipher对象进行初始化
|
|
|
+ deCipher.init(Cipher.DECRYPT_MODE, key);
|
|
|
+ byte[] decBytes = null;//deCipher.doFinal(srcBytes);
|
|
|
+ if (segmentSize > 0)
|
|
|
+ decBytes = cipherDoFinal(deCipher, srcBytes, segmentSize); //分段加密
|
|
|
+ else
|
|
|
+ decBytes = deCipher.doFinal(srcBytes);
|
|
|
+
|
|
|
+ String decrytStr = new String(decBytes);
|
|
|
+ return decrytStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 秘钥对
|
|
|
+ */
|
|
|
+ public class KeyPairInfo {
|
|
|
+ public KeyPairInfo(int keySize) {
|
|
|
+ setKeySize(keySize);
|
|
|
+ }
|
|
|
+
|
|
|
+ public KeyPairInfo(String publicKey, String privateKey) {
|
|
|
+ setPrivateKey(privateKey);
|
|
|
+ setPublicKey(publicKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ String privateKey;
|
|
|
+ String publicKey;
|
|
|
+ int keySize = 0;
|
|
|
+
|
|
|
+ public String getPrivateKey() {
|
|
|
+ return privateKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setPrivateKey(String privateKey) {
|
|
|
+ this.privateKey = privateKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getPublicKey() {
|
|
|
+ return publicKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setPublicKey(String publicKey) {
|
|
|
+ this.publicKey = publicKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getKeySize() {
|
|
|
+ return keySize;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setKeySize(int keySize) {
|
|
|
+ this.keySize = keySize;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|