我正在为服务器编写发送电子邮件的模块。在客户端应用程序中,用户可以添加多个接收器,每个接收器都有自己的公钥。我想使用多个密钥加密附件。例如,如果我添加了3个接收者,那么附件应该用3个不同的公钥加密。我使用bouncy castle来实现这一点,但它只适用于加密过程中的第一个公钥。我的意思是只有第一个人可以使用自己的私钥解密,其余的都不起作用。我为每个键添加方法的代码如下所示:
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);
}
谁能帮帮我,告诉我做错了什么?
谢谢你的帮助。
[编辑]这段代码有效,我加载多个键的方法有问题。
一年后我也有同样的问题。我希望你已经解决了你的问题。我在这里写我的解决方案,以防其他人有类似的问题。
你的加密代码没有问题。问题可能出在解密中。对于加密的数据对象,应使用存储在对象中的密钥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循环。
如果使用RSA-OAEP是不可能的,你能给出同样的方法吗? 谢谢
我使用RSA_public_encrypt函数发送加密数据到套接字。我正在读取公钥。使用"pkey=PEM_read_PUBKEY(f, NULL, NULL, NULL);"函数的PEM文件。从上面的函数中检索的pkey是类型EVP_PKEY*,我不能在函数RSA_public_encrypt中使用。(RSA_public_encrypt使用RSA*类型密钥) 如何将EVP_PKEY*PKEY转
问题内容: 我正在编写一个用于传输文件的小型应用程序,或多或少地将其作为一种学习更多编程加密基础的方法。这个想法是生成一个RSA密钥对,交换公共密钥,并发送AES iv和密钥以进一步解密。我想用接收者的RSA公钥加密AES密钥,如下所示: 然后,我将密钥值写给接收器,并按如下方式解密: 在控制台的另一端,我将其作为输出: 此外,如果我创建一个大小为16的字节数组,并将cipher.doFinal(
我使用Delphi XE和Lockbox3.5,我想加密一个字符串,该字符串具有支付网关提供的公钥,需要操作,公钥类似于:------开始公钥------这里的职员------结束公钥------我无法使RSA编解码器读取该公钥,我的代码如下: 编解码器cdcRA链接到CryptoLibrary,密码为(RSA公钥加密系统*),链接模式为空,但此代码失败,并出现内存不足错误。谢谢你的提示。。 演示
并且我将这个函数称为用RSA公钥加密DSA密钥的函数:
一段时间以来,我一直在阅读CodeProject a的一篇文章,该文章解释了如何使用RSA提供程序进行加密和解密: RSA私钥加密 虽然2009年的旧版本有缺陷,但2012年的新版本(支持System.Numerics.BigInteger)似乎更可靠。但这个版本缺少的是一种使用公钥加密和使用私钥解密的方法。 所以,我自己也试过了,但解密时会收到垃圾。我对RSA提供商不熟悉,所以我对这里一无所知。