gpt4 book ai didi

java - 在 Java 中读取 OpenSSL 生成的 PEM/DER 格式的 S/MIME 消息

转载 作者:行者123 更新时间:2023-11-30 11:21:47 26 4
gpt4 key购买 nike

我需要能够用 Java 读取从 OpenSSL 生成的 S/MIME 文件。 openssl 命令看起来像

openssl smime -encrypt -in test_message.txt -out test_out.pem -outform pem certificate.pem

这会创建一个看起来像这样的文件

-----BEGIN PKCS7-----
MIIBkwYJKoZIhvcNAQcDoIIBhDCCAYACAQAxggE+MIIBOgIBADAiMBoxGDAWBgNV
BAMTD0ZvcmRTRE5TZWN1cml0eQIEUw5nyTANBgkqhkiG9w0BAQEFAASCAQBK9wAV
wAXRM7oMWJz113VX7Tb/MslQatHZH2oaX5XJnIJrvnTv9T3irQR9H+pegh1q6OZv
v4Mz/QBFO2iq4tv6xGHE8hl0ZdmNCUdTN41qutZP2+N1YrKi9QLmnuAi3BkEzzeW
YTGvE8xGsjNlTLOjz7P5lZdCWpGJmdPeUDP0IYsOsuMspPcujyOdA5y++y6x90WF
J3ovzPhCRU7303EhdQ1hHse8KTen56XZflL3zhnT2KGtN/Pq3aZ1MVhmLZ+EZuUF
ygxlwCXi3FUx7P35XZAGpTUPFM2sz5p+oSrcxA+fsUgiMb96tfaXZLYE753mA2tZ
WfCRd86nzJsVE/YhMDkGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIAoAQIqd23
FXgqdaSAEHLeYH0LG9G+UfCBxQOalIE=
-----END PKCS7-----

我目前正在使用 BouncyCaSTLe 尝试读取 test_out.pem,

....
MimeMessage mimeMessage = new MimeMessage(session, new FileInputStream("test_out.pem"));
SMIMEEnveloped smimeEnveloped = new SMIMEEnveloped(mimeMessage);
...

但我不知道如何让它接受没有 MIME header 的消息,因为我收到以下错误:

java.lang.NullPointerException: null
at org.bouncycastle.cms.CMSEnvelopedData.<init>(Unknown Source) ~[bcpkix-jdk15on-1.50.jar:1.50.0]
at org.bouncycastle.cms.CMSEnvelopedData.<init>(Unknown Source) ~[bcpkix-jdk15on-1.50.jar:1.50.0]
at org.bouncycastle.mail.smime.SMIMEEnveloped.<init>(Unknown Source) ~[bcmail-jdk15on-1.50.jar:1.50.0]

读取这样的 PEM(或 DER)格式文件并能够使用 java.security.PrivateKey 解密它的最佳方法是什么?

最佳答案

以下是使用 BouncyCaSTLe 1.57(受 this article 启发)进行解密的方法:

import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.KeyTransRecipientInformation;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipient;
import org.bouncycastle.util.encoders.Base64;

import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Collection;

public class PKCS7Decryptor {

private PrivateKey privateKey;

public PKCS7Decryptor(String privateKeyStr) {
try {
byte[] privateKeyData = extractRawData(privateKeyStr, "PRIVATE KEY");
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(privateKeyData);
KeyFactory kf = KeyFactory.getInstance("RSA");
privateKey = kf.generatePrivate(kspec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new RuntimeException("Unable to parse private key");
}
}

public String decrypt(String encryptedText) throws CMSException {
byte[] data = extractRawData(encryptedText, "PKCS7");

CMSEnvelopedData envelopedData = new CMSEnvelopedData(data);

Collection<RecipientInformation> recipients = envelopedData.getRecipientInfos().getRecipients();
KeyTransRecipientInformation recipientInfo = (KeyTransRecipientInformation) recipients.iterator().next();
JceKeyTransRecipient recipient = new JceKeyTransEnvelopedRecipient(privateKey);

return new String(recipientInfo.getContent(recipient));
}

private byte[] extractRawData(String text, String dataType) {
return Base64.decode(text
.replace(String.format("-----BEGIN %s-----", dataType), "")
.replace(String.format("-----END %s-----", dataType), ""));
}
}

一些解释:

  • 在类构造函数中,私钥被转换为适当的格式
  • 页眉和页脚(如“-----BEGIN PKCS7-----”)已删除,内容经过 base64 解码

关于java - 在 Java 中读取 OpenSSL 生成的 PEM/DER 格式的 S/MIME 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22083514/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com