【问题标题】:Encryption using multiple RSA public keys使用多个 RSA 公钥加密
【发布时间】:2016-08-30 20:40:29
【问题描述】:

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

有人可以帮助我并告诉我我做错了什么吗?

感谢您的每一个帮助。

[编辑] 此代码有效,我在加载多个键的方法时遇到问题。

【问题讨论】:

  • 查看stackoverflow.com/questions/38846/…了解更标准的方法
  • 我知道我需要生成对称密钥,用它来加密文件,然后使用每个公钥加密这个密钥,但我不知道如何使用 bouncycastle 来做到这一点。我需要使用任何使用 OpenPGP 标准的程序进行解密。

标签: java encryption rsa bouncycastle public-key-encryption


【解决方案1】:

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

您的加密代码没有问题。问题可能出在解密中。对于加密的数据对象,应使用与对象一起存储的密钥 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 循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-04
    • 2014-06-23
    • 2011-11-07
    • 2011-11-10
    • 2013-05-07
    • 2011-08-16
    • 2014-01-07
    相关资源
    最近更新 更多