
me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil Maven / Gradle / Ivy
package me.chanjar.weixin.cp.util.crypto;
import com.google.common.base.CharMatcher;
import com.google.common.io.BaseEncoding;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import sun.security.util.DerInputStream;
import sun.security.util.DerValue;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.util.Base64;
public class WxCpCryptUtil extends WxCryptUtil {
public WxCpCryptUtil(WxCpConfigStorage wxCpConfigStorage) {
/*
* @param token 公众平台上,开发者设置的token
* @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
* @param appidOrCorpid 公众平台appid
*/
String encodingAesKey = wxCpConfigStorage.getAesKey();
String token = wxCpConfigStorage.getToken();
String corpId = wxCpConfigStorage.getCorpId();
this.token = token;
this.appidOrCorpid = corpId;
this.aesKey = BaseEncoding.base64().decode(CharMatcher.whitespace().removeFrom(encodingAesKey));
}
/**
* 判断使用PKCS8或者PKCS1进行解密
*
* @param encryptRandomKey 使用PUBLICKEY_VER指定版本的公钥进行非对称加密后base64加密的内容
* @param msgAuditPriKey 会话存档私钥
* @param pkcs1 使用什么方式进行解密,1代表使用PKCS1进行解密,2代表PKCS8进行解密 ...
* @return
* @throws Exception
*/
public static String decryptPriKey(String encryptRandomKey, String msgAuditPriKey, Integer pkcs1) throws Exception {
if (pkcs1 == null) {
throw new WxErrorException("请配置会话存档解密方式");
}
if (pkcs1.intValue() == 1) {
return decryptPriKeyByPKCS1(encryptRandomKey, msgAuditPriKey);
}
return decryptPriKeyByPKCS8(encryptRandomKey, msgAuditPriKey);
}
/**
* PKCS8 解密私钥
*
* @param encryptRandomKey
* @param msgAuditPriKey
* @return
* @throws Exception
*/
public static String decryptPriKeyByPKCS8(String encryptRandomKey, String msgAuditPriKey) throws Exception {
String privateKey = msgAuditPriKey.replaceAll("\\n", "")
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll(" ", "");
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] utf8 = cipher.doFinal(Base64.getDecoder().decode(encryptRandomKey));
return new String(utf8, "UTF-8");
}
/**
* 会话存档,PKCS1 解密私钥
* 企业获取的会话内容将用公钥加密,企业用自行保存的私钥解开会话内容数据
*
* @param encryptRandomKey 使用PUBLICKEY_VER指定版本的公钥进行非对称加密后base64加密的内容,需要业务方先base64 decode处理后,再使用指定版本的私钥进行解密,得出内容。String类型
* @param msgAuditPriKey 会话存档私钥
* @return
* @throws Exception
*/
public static String decryptPriKeyByPKCS1(String encryptRandomKey, String msgAuditPriKey) throws Exception {
String privateKey = msgAuditPriKey.replaceAll("\\n", "")
.replace("-----BEGIN RSA PRIVATE KEY-----", "")
.replace("-----END RSA PRIVATE KEY-----", "")
.replaceAll(" ", "");
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
DerValue[] seq = new DerInputStream(keyBytes).getSequence(0);
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(seq[1].getBigInteger(), seq[2].getBigInteger(),
seq[3].getBigInteger(), seq[4].getBigInteger(),
seq[5].getBigInteger(), seq[6].getBigInteger(),
seq[7].getBigInteger(), seq[8].getBigInteger());
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] utf8 = cipher.doFinal(Base64.getDecoder().decode(encryptRandomKey));
return new String(utf8, "UTF-8");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy