当前位置: 首页 > 知识库问答 >
问题:

使用多个RSA公钥进行加密

宋典
2023-03-14

我正在为服务器编写发送电子邮件的模块。在客户端应用程序中,用户可以添加多个接收器,每个接收器都有自己的公钥。我想使用多个密钥加密附件。例如,如果我添加了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);
}

谁能帮帮我,告诉我做错了什么?

谢谢你的帮助。

[编辑]这段代码有效,我加载多个键的方法有问题。

共有1个答案

殷承恩
2023-03-14

一年后我也有同样的问题。我希望你已经解决了你的问题。我在这里写我的解决方案,以防其他人有类似的问题。

你的加密代码没有问题。问题可能出在解密中。对于加密的数据对象,应使用存储在对象中的密钥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提供商不熟悉,所以我对这里一无所知。