Java 解密电子邮件附件(.p7m 文件)
Java decrypt email attachment (.p7m file)
我有一个 .p7m 格式的电子邮件附件和一个包含私钥和证书的 .pem 文件。
使用 OpenSSL 我可以用这个命令解密文件:
openssl smime -decrypt -inform DER -in fileToDecrypt.p7m -inkey privateKey.pem -out destinationFile
但是在Java中使用bouncycastle,我无法解密它。
我用这段代码读取了私钥:
PEMReader pemReader = new PEMReader(new InputStreamReader(new FileInputStream(privateKeyName)));
Object obj;
PrivateKey key = null;
X509Certificate cert1 = null;
X509Certificate cert2 = null;
obj = pemReader.readObject();
if (obj instanceof PrivateKey) {
key = (PrivateKey) obj;
System.out.println("Private Key found");
}
obj = pemReader.readObject();
if(obj instanceof X509Certificate){
cert1 = (X509Certificate) obj;
System.out.println("cert found");
}
obj = pemReader.readObject();
if(obj instanceof X509Certificate){
cert2 = (X509Certificate) obj;
System.out.println("cert found");
}
打印出来:
Private Key Found
cert found
cert found
键的类型是:
System.out.println(key.getAlgorithm());
System.out.println(cert1.getSigAlgName());
System.out.println(cert2.getSigAlgName());
RSA
SHA256WithRSAEncryption
SHA256WithRSAEncryption
如果我尝试这样解密:
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
Path path = Paths.get("fileToDecrypt.p7m");
byte[] data = Files.readAllBytes(path);
byte[] decryptedData = cipher.doFinal(data);
我得到:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
我有这两个文件:
- fileToDecrypt.p7m
- privateKey.pem:包含RSA私钥和两个X508证书
而且我不知道从哪里开始用什么解密什么以及如何解密?
问题解决方案:
private static byte[] cmsDecrypt(byte[] message, PrivateKey key) throws
Exception {
CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(message);
RecipientInformationStore recipients = ep.getRecipientInfos();
Collection c = recipients.getRecipients();
Iterator iter = c.iterator();
RecipientInformation recipient = (RecipientInformation) iter.next();
return recipient.getContent(key, new BouncyCastleProvider());
}
Path path = Paths.get("fileToDecrypt.p7m");
byte[] data = Files.readAllBytes(path);
try {
System.out.println(new String(cmsDecrypt(data, key)));
} catch (Exception e) {
e.printStackTrace();
}
我有一个 .p7m 格式的电子邮件附件和一个包含私钥和证书的 .pem 文件。 使用 OpenSSL 我可以用这个命令解密文件:
openssl smime -decrypt -inform DER -in fileToDecrypt.p7m -inkey privateKey.pem -out destinationFile
但是在Java中使用bouncycastle,我无法解密它。 我用这段代码读取了私钥:
PEMReader pemReader = new PEMReader(new InputStreamReader(new FileInputStream(privateKeyName)));
Object obj;
PrivateKey key = null;
X509Certificate cert1 = null;
X509Certificate cert2 = null;
obj = pemReader.readObject();
if (obj instanceof PrivateKey) {
key = (PrivateKey) obj;
System.out.println("Private Key found");
}
obj = pemReader.readObject();
if(obj instanceof X509Certificate){
cert1 = (X509Certificate) obj;
System.out.println("cert found");
}
obj = pemReader.readObject();
if(obj instanceof X509Certificate){
cert2 = (X509Certificate) obj;
System.out.println("cert found");
}
打印出来:
Private Key Found
cert found
cert found
键的类型是:
System.out.println(key.getAlgorithm());
System.out.println(cert1.getSigAlgName());
System.out.println(cert2.getSigAlgName());
RSA
SHA256WithRSAEncryption
SHA256WithRSAEncryption
如果我尝试这样解密:
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
Path path = Paths.get("fileToDecrypt.p7m");
byte[] data = Files.readAllBytes(path);
byte[] decryptedData = cipher.doFinal(data);
我得到:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
我有这两个文件:
- fileToDecrypt.p7m
- privateKey.pem:包含RSA私钥和两个X508证书
而且我不知道从哪里开始用什么解密什么以及如何解密?
问题解决方案:
private static byte[] cmsDecrypt(byte[] message, PrivateKey key) throws
Exception {
CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(message);
RecipientInformationStore recipients = ep.getRecipientInfos();
Collection c = recipients.getRecipients();
Iterator iter = c.iterator();
RecipientInformation recipient = (RecipientInformation) iter.next();
return recipient.getContent(key, new BouncyCastleProvider());
}
Path path = Paths.get("fileToDecrypt.p7m");
byte[] data = Files.readAllBytes(path);
try {
System.out.println(new String(cmsDecrypt(data, key)));
} catch (Exception e) {
e.printStackTrace();
}