简介
企业微信获取到的加密内容为企业微信产生。RSA使用PKCS1,而不是PKCS8,但是填充的公钥要求是PKCS8,这是企业微信巨坑的地方。找到此问题后,就需要单独转换私钥key了。废话不多说,以下是代码,仅做记录,供同行人少走弯路。
jar坐标
compile group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.69'
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69'
compile 'org.bouncycastle:bcpg-jdk16:1.46'
代码
/**
* PKCS8私钥key,转换为PKCS1私钥key
* @param privateKey PKCS8 RSA私钥(即-----BEGIN PRIVATE KEY-----开头)
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKey(String privateKey) throws Exception {
//PKCS8格式转换为PKCS1格式
String privKeyPEMNew = privateKey.replaceAll("\\n", "")
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll(" ", "");
byte[] e = org.apache.tomcat.util.codec.binary.Base64.decodeBase64(privKeyPEMNew); //base64无法解析换行符,-等特殊符号
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(e);
RSAPrivateKey pkcs1Key = RSAPrivateKey.getInstance(pki.parsePrivateKey());
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(pkcs1Key.getModulus(),pkcs1Key.getPrivateExponent());
// 实例化KeyFactory对象,并指定 RSA 算法
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 获得 PrivateKey 对象
PrivateKey realprivateKey = keyFactory.generatePrivate(rsaPrivateKeySpec);
return realprivateKey;
}
/**
* 通过PKCS8私钥key解密RSA PKCS1
*/
public static String encryptByPrivateKey(String content, String privateKey) throws Exception {
Security.addProvider(new BouncyCastleProvider());
Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
rsa.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKey));
byte[] utf8 = rsa.doFinal(org.apache.tomcat.util.codec.binary.Base64.decodeBase64(content));
String result = new String(utf8, "UTF-8");
return result;
}