第三方使用公钥.crt加密后返回的内容,需要使用私钥解密.pem

返回内容格式如下

MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
Content-Transfer-Encoding: base64 MIICEQYJKoZIhvcNAQcDoIICAjCCAf4CAQAxggFAMIIBPAIBADAkMBYxFDASBgNV
BAMTC1NpbmFwdElRIENBAgoeg+bBAAAAAAAMMA0GCSqGSIb3DQEBAQUABIIBACGx
OPGANR0bAlwPxlYt6DBTEPinPc2eiduiYLXEOftEmDA3vLNyeQ+Q1sxfYj1U5K2o
26qKr937yNwrtZ1VTird4NXHiR60Gtm0VJ+sd88XylHe2VxJrrNWHFPwoT+q7nfy
IT6cfMgfOMzA1YO3/efWKEFJgmiUoeo+PZgrcRr4PIMYIFnnxQNKz+iwutfd+O44
H5wIviHsqGjiSqoVzEg5/pWh07aZ9hr/2CNGbDwBH4f+hucJTzt98tvMhrjFvbDy
uiegAgxN/nolzRQv7lUlLvUrNJSOiFM5/1BWUfoiTLRgoseHjt9RxPKb8WRpul7f
Om0hWxXl0mWus9GLBCIwgbQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIBcIBRSKJ
WEuAgZCcvoeat07ncIZI6owiP7WMSC9RXfuRQ//FKuBx+cpJdHnGkYuPTA3gJJca
kTis/5rpDiE7bmiCiDlMBdoM1h+A0jSpR78nOCsJuJI08clAJQmj82ACbPmwRUwg
OCrkTLUqbJ7brsYJeMYZWyBZIAL3bKtgqi2VRqOPerzaxOcjqv873wed/2kRUrhV
gMw9bSc=

解密开始,你需要提取内容部分,并去掉换行,让内容部分保持在一行

比如:MIICEQYJKoZIhvcNAQcDoIICAjCCAf4CAQAxggFAMIIBPAIBADAkMBYxFDASBgNVBAMTC......

maven pom.xml需要引用

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.60</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>

JAVA解密加密工具类

package com.perfect.all.core.util.pay.toc2p;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyPair;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;
import java.util.Collection;
import java.util.Iterator; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSEnvelopedDataParser;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; public class Pcks7EncryptOrDecryptUtil { private static final String PRIVATE_KEY_PATH = "/xxxx.pem";
private static final String PRIVATE_KEY_PASSWORD="xxxx";
public static final String PUBLIC_KEY_PATH="/xxx.crt"; private static PrivateKey PRIVATE_KEY = null;
private static RSAPublicKey PUBLIC_KEY = null;
private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; static {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
} public static void main(String[] args) throws Exception {
String sendConent="<PaymentProcessRequest><version>3.0</version><timeStamp>161018173004</timeStamp><merchantID>764764000001350</merchantID><processType>R</processType><invoiceNo>THBPOps180808153209</invoiceNo><actionAmount>0.01</actionAmount><hashValue>E8CCDCDBDBB7428CF0CC9F06AB30B595067F4C89</hashValue></PaymentProcessRequest>";
String rsaPubEncrypt = encryptByRsaPub(PUBLIC_KEY_PATH,sendConent,"utf-8");//加密数据
System.out.println(rsaPubEncrypt);
System.out.println(decryptByContent(rsaPubEncrypt, PRIVATE_KEY_PATH, PRIVATE_KEY_PASSWORD)); //解密数据 //第三方返回的数据
String encryptContent = "MIICcgYJKoZIhvcNAQcDoIICYzCCAl8CAQA......";
System.out.println(decryptByContent(encryptContent, PRIVATE_KEY_PATH, PRIVATE_KEY_PASSWORD)); } /**
* 使用私钥加密
*/
public static String encryptByRsaPub(String content) {
return encryptByRsaPub( PUBLIC_KEY_PATH,content,"utf-8");
} /**
* 使用私钥加密
*/
public static String encryptByRsaPub(String publicKeyPath , String content,String charSet) { try {
X509Certificate cert = getX509Certificate(publicKeyPath);
//添加数字信封
CMSTypedData msg = new CMSProcessableByteArray(content.getBytes(charSet)); CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(
cert).setProvider("BC")); CMSEnvelopedData ed = edGen.generate(msg,
new JceCMSContentEncryptorBuilder(PKCSObjectIdentifiers.rc4)
.setProvider("BC").build()); String rslt = new String(Base64.getEncoder().encode(ed.getEncoded())); System.out.println(rslt);
return rslt;
} catch (CertificateEncodingException | CMSException | IOException e) {
e.printStackTrace();
}
return null;
} /**
* 使用公钥解密
* @param encryptContent 比如:MIICEQYJKoZIhvcNAQcDoIICAjCCAf4CAQAxggFAMIIBPAIBADAkMBYxFDASBgNVBAMTC......
* @param privatePemKeyPath xxxx.pem
* @param privatePemKeyPassword
* @return
*/
public static String decryptByContent(String encryptContent,String privatePemKeyPath,String privatePemKeyPassword) {
return decryptByContent(encryptContent,getPrivateKey(privatePemKeyPath, privatePemKeyPassword));
} public static String decryptByContent(String encryptContent,PrivateKey privateKey) {
return decryptByContent(Base64.getDecoder().decode(encryptContent),privateKey);
}
public static String decryptByContent(String encryptContent) {
return decryptByContent(Base64.getDecoder().decode(encryptContent),getPrivateKey(PRIVATE_KEY_PATH, PRIVATE_KEY_PASSWORD));
} public static String decryptByContent(byte[] encryptContent,PrivateKey privateKey) {
try {
CMSEnvelopedDataParser cmsEnvelopedDataParser = new CMSEnvelopedDataParser(encryptContent);
Collection<RecipientInformation> recInfos = cmsEnvelopedDataParser.getRecipientInfos().getRecipients();
Iterator<RecipientInformation> recipientIterator = recInfos.iterator();
if (recipientIterator.hasNext()) {
RecipientInformation recipientInformation = (RecipientInformation) recipientIterator.next();
JceKeyTransEnvelopedRecipient jceKeyTransEnvelopedRecipient = new JceKeyTransEnvelopedRecipient(privateKey);
byte[] contentBytes = recipientInformation.getContent(jceKeyTransEnvelopedRecipient);
String decryptContent = new String(contentBytes);
return decryptContent;
}
} catch (CMSException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("decrypt error");
return null;
} public static PrivateKey getPrivateKey(String pemFilePath, String password){
if(PRIVATE_KEY != null) {
return PRIVATE_KEY;
}
Security.addProvider(new BouncyCastleProvider());
KeyPair kp;
try{
kp = (KeyPair)initKeyPair(new File(pemFilePath), password.toCharArray());
PrivateKey privateKey = kp.getPrivate();
return (PRIVATE_KEY = privateKey);
}catch(Exception e){
e.printStackTrace(); } return null;
} public static KeyPair initKeyPair(File pemFile, char[] password) throws Exception{
PEMParser pemParser = new PEMParser(new FileReader(pemFile));
Object object = pemParser.readObject();
pemParser.close();
PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password);
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
//获得密钥对
KeyPair kp = null;
if(object instanceof PEMEncryptedKeyPair){
kp = converter.getKeyPair(((PEMEncryptedKeyPair)object).decryptKeyPair(decProv));
}else{
kp = converter.getKeyPair((PEMKeyPair)object);
}
return kp;
} public static RSAPublicKey getRSAPublicKey(String crtFileName) {
if(PUBLIC_KEY != null) {
return PUBLIC_KEY;
}
return (PUBLIC_KEY = (RSAPublicKey) getX509Certificate(crtFileName).getPublicKey());
} /**
* 获取公钥
*/
public static X509Certificate getX509Certificate(String crtFileName) {
try {
CertificateFactory certificatefactory;
X509Certificate cert;
// 使用公钥对对称密钥进行加密 //若此处不加参数 "BC" 会报异常:CertificateException -
certificatefactory = CertificateFactory.getInstance("X.509", "BC");
// 读取.crt文件;你可以读取绝对路径文件下的crt,返回一个InputStream(或其子类)即可。
InputStream bais = new FileInputStream(crtFileName); cert = (X509Certificate) certificatefactory.generateCertificate(bais);
return cert;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
} public static String byteArrayToString(byte[] data) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < data.length; i++) {
// 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
// 取出字节的低四位 作为索引得到相应的十六进制标识符
stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
if (i < data.length - 1) {
stringBuilder.append(' ');
}
}
return stringBuilder.toString();
} public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
} /** * Convert char to byte * @param c char * @return byte */
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
} }

JAVA 解密pkcs7(smime.p7m)加密内容 ,公钥:.crt 私钥:.pem 使用Bouncy Castle生成数字签名、数字信封的更多相关文章

  1. 几个例子理解对称加密与非对称加密、公钥与私钥、签名与验签、数字证书、HTTPS加密方式

    # 原创,转载请留言联系 为什么会出现这么多加密啊,公钥私钥啊,签名啊这些东西呢?说到底还是保证双方通信的安全性与完整性.例如小明发一封表白邮件给小红,他总不希望给别人看见吧.而各种各样的技术就是为了 ...

  2. 【Java密码学】使用Bouncy Castle生成数字签名、数字信封

    Bouncy Castle(轻量级密码术包)是一种用于 Java 平台的开放源码的轻量级密码术包,它支持大量的密码术算法,并提供 JCE 1.2.1 的实现.最近项目上正好用到了Bouncy Cast ...

  3. 大话https演化过程(对称加密、非对称加密、公钥、私钥、数字签名、数字证书)

    大话https演化过程(包括概念:对称加密.非对称加密.公钥.私钥.数字签名.数字证书.https访问全过程)   在网络上发送数据是非常不安全的,非常容易被劫持或是被篡改,所以每次定向发送数据你都可 ...

  4. JAVA生成RSA非对称型加密的公钥和私钥(利用JAVA API)

    非对称型加密非常适合多个客户端和服务器之间的秘密通讯,客户端使用同一个公钥将明文加密,而这个公钥不能逆向的解密,密文发送到服务器后有服务器端用私钥解密,这样就做到了明文的加密传送. 非对称型加密也有它 ...

  5. RSA - 原理、特点(加解密及签名验签)及公钥和私钥的生成

    Wiki - RSA加密演算法 Wiki - 欧拉函数 Wiki - 模反元素 ASN.1 格式标准 RSA算法原理(二) 注意: RSA 加密或签名后的结果是不可读的二进制,使用时经常会转为 BAS ...

  6. 对SHH的公钥和私钥的简单理解

    SSH是在应用层和传输层基础上的安全协议 SSH提供了两种级别的安全验证: 第一基于密码的安全验证:账号.密码,但可能有别的服务器冒充真正的服务器,无法避免被“中间人”攻击(man-in-the-mi ...

  7. C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法

    因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger ...

  8. 对于如何从SM2的pfx证书文件中解析公钥和私钥,并从二次加密的密文中解密

    首先呢,由于我的域名之前处理点问题,然后备案第二个网站时候,第一个网站没法访问,所以备案没过,阿里云告诉我要删除一个网站的备案,但是他没告诉我要删除主体,所以我的备案主体成了空壳主体,要传真或者发快递 ...

  9. Java加密与解密笔记(三) 非对称加密

    非对称的特点是加密和解密时使用的是不同的钥匙.密钥分为公钥和私钥,用公钥加密的数据只能用私钥进行解密,反之亦然. 另外,密钥还可以用于数字签名.数字签名跟上文说的消息摘要是一个道理,通过一定方法对数据 ...

随机推荐

  1. VB查询数据库之登陆窗体——机房收费总结(一)

    机房收费系统已经做了很长一段时间了,虽然到目前为止,仍然没有结束,但已经结节尾声了.我感觉现在有必要回首总结一下整个机房收费系统. 除了结账做了一半,报表接触一点之外,其他的都基本上差不多了.从做过的 ...

  2. AGC 012 C - Tautonym Puzzle

    题面在这里! 神仙构造啊qwqwq. 窝一开始只想到一个字符串长度是 O(log(N)^2) 的做法:可以发现一段相同的长度为n的字符串的贡献是 2^(n-1)-1 ,可以把它看成类二进制,枚举用了多 ...

  3. ARC-100 E - Or Plus Max

    题面在这里! 我们如果可以求出 f[x] = max{ a[i] + a[j] , i!=j && i or j == x},那么就可以通过前缀max直接递推答案了. 但是这个玩意不是 ...

  4. BZOJ 1827 [Usaco2010 Mar]gather 奶牛大集会(树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1827 [题目大意] 给出一棵有点权和边权的树, 请确定一个点,使得每个点到这个点的距离 ...

  5. 【推导】【凸包】MIPT-2016 Pre-Finals Workshop, Taiwan NTU Contest, Sunday, March 27, 2016 Problem D. Drawing Hell

    平面上n个点,两个人交替决策,用线段连接两个点,但不能跨越其他点或者已经存在的线段.不能做的人算输,问你谁赢. 实际上,跟两个人的决策无关,n个点将平面三角剖分,只需要算出有几条边即可. 凸包上如果有 ...

  6. CentOS6安装NodeJS(非编译)

    由于编译安装需要各种依赖库,会远远高于生产环境下的默认版本,强行升级会产生很多不必要的问题,所以一般用官网编译好的安装 下载nodejs并安装 wget https://nodejs.org/dist ...

  7. 虚拟PDF打印机

    doPDF虚拟打印机 doPDF 是一个免费的PDF转换器,可同时运用于商业和个人,它把自己安装为一个打印机驱动,允许从任意一个有打印输出的Windows程序中打印,还包含缩放,质量定义和页面大小定义 ...

  8. 游戏用户接口设计的一些小原则(摘自 game coding complete)

    1.没有坏之前不要修理 2.简单的操作却有非常复杂的结果时,要小心设计. 3.记得给玩家反馈. 4.玩家不知道该功能,可能就根本不会用这个功能. 5.观察并持续改进.(给不熟悉该设计的人玩,站在他们后 ...

  9. CMakeFile命令之file

    file:文件操作命令. file(WRITE filename "message towrite"... ) WRITE 将一则信息写入文件’filename’中,如果该文件存在 ...

  10. WINXP上安装及使用SqlMap之方法

    1.首先下载SqlMap 点击下载.2.其次下载用于Windows系统的Python ……点击这里…… 3.然后安装Python:Python默认安装的路径是“C:\Python”(你也可以修改安装路 ...