我正在为服务器编写模块,用于发送电子邮件。在客户端应用程序中,用户可以添加许多收件人,每个收件人都有自己的公钥。我想使用多个密钥加密附件。例如,如果我添加3个收件人,则应使用3个不同的公钥加密附件。我使用充气城堡来做到这一点,但它只适用于加密过程中的第一个公钥。我的意思是,只有第一个人可以使用自己的私钥解密,其余的它不起作用。 我为每个键添加方法的代码如下:
PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
for (PGPPublicKey publicKey : publicKeys) {
encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
}
整个方法如下:
public File encryptFile(String fileName,
boolean armor,
boolean withIntegrityCheck) throws IOException,
NoSuchProviderException,
PGPException {
Security.addProvider(new BouncyCastleProvider());
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PGPCompressedDataGenerator comData
= new PGPCompressedDataGenerator(PGPCompressedData.UNCOMPRESSED);
PGPUtil.writeFileToLiteralData(comData.open(bOut),
PGPLiteralData.BINARY,
new File(fileName));
comData.close();
BcPGPDataEncryptorBuilder dataEncryptor
= new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_256);
dataEncryptor.setWithIntegrityPacket(withIntegrityCheck);
dataEncryptor.setSecureRandom(new SecureRandom());
PGPEncryptedDataGenerator encryptedDataGenerator
= new PGPEncryptedDataGenerator(dataEncryptor);
for (PGPPublicKey publicKey : publicKeys) {
encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
}
byte[] bytes = bOut.toByteArray();
FileOutputStream localByteArrayOutputStream = new FileOutputStream(fileName);
Object localObject = localByteArrayOutputStream;
if (armor) {
localObject = new ArmoredOutputStream((OutputStream) localObject);
}
OutputStream localOutputStream = encryptedDataGenerator.open((OutputStream) localObject,
bytes.length);
localOutputStream.write(bytes);
localOutputStream.close();
return new File(fileName);
}
有人可以帮助我并告诉我我做错了吗?
感谢您的帮助。
[编辑] 这段代码有效,我在加载多个键的方法上遇到了问题。
答案 0 :(得分:2)
嗯,一年后我遇到了同样的问题。我希望你解决了你的问题。我在这里写我的解决方案,以防其他人有类似的问题。
您的加密代码没有问题。问题可能在于解密。对于加密数据对象,应使用与对象一起存储的密钥ID找到正确的密钥。我的解密过程如下所示:
private byte[] decryptWithKey(byte[] bytes, PGPSecretKey secKey, String pass)
throws PGPException, IOException {
PBESecretKeyDecryptor keyDec = new JcePBESecretKeyDecryptorBuilder(
new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build())
.setProvider("BC").build(pass.toCharArray());
ByteArrayOutputStream bout = new ByteArrayOutputStream();
PGPPrivateKey privateKey = secKey.extractPrivateKey(keyDec);
PublicKeyDataDecryptorFactory dec1 =
new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(privateKey);
JcaPGPObjectFactory objFact = new JcaPGPObjectFactory(bytes);
PGPEncryptedDataList encList = (PGPEncryptedDataList) objFact.nextObject();
PGPPublicKeyEncryptedData encD = null;
for(Iterator<PGPPublicKeyEncryptedData> it = encList.iterator(); it.hasNext(); ) {
PGPPublicKeyEncryptedData end = it.next();
if (secKey.getKeyID() == end.getKeyID()) {
encD = end;
break;
}
}
assert encD != null: "Cannot find encrypted data with key: "
+ Long.toHexString(secKey.getKeyID());
InputStream in = encD.getDataStream(dec1);
byte[] buf = new byte[BufferSize];
for (int len; (len = in.read(buf)) >= 0; ) {
bout.write(buf, 0, len);
}
bout.close();
return bout.toByteArray();
}
密钥是for循环,它找到加密对象的匹配密钥。