简体   繁体   English

使用多个RSA公钥进行加密

[英]Encryption using multiple RSA public keys

I'm writing module for server which will send e-mails. 我正在为服务器编写模块,它将发送电子邮件。 In client application user can add many receipients and each of them has its own public key. 在客户端应用程序中,用户可以添加许多收件人,每个收件人都有自己的公钥。 I want to encrypt attachments using multiple keys. 我想使用多个密钥加密附件。 For example if I add 3 receipients then attachments should be encrypted with 3 different public keys. 例如,如果我添加3个收件人,则应使用3个不同的公钥加密附件。 I'm using bouncy castle to do that but it works only for the first public key in encryption process. 我正在使用充气城堡来做到这一点,但它只适用于加密过程中的第一个公钥。 I mean thath only the first person can decrypt using its own private key, for the rest it doesn't work. 我的意思是只有第一个人可以使用自己的私钥解密,其余的则不起作用。 My code for adding methods for each key looks like: 我为每个键添加方法的代码如下所示:

PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);

for (PGPPublicKey publicKey : publicKeys) {
        encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
}

Whole method looks like: 整个方法看起来像:

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);
}

Can someone help me and tell me what I'm doing wrong? 有人可以帮助我并告诉我我做错了什么吗?

Thank you for every help. 谢谢你的帮助。

[EDIT] This code works, I had problem in method loading multiple keys. [编辑]此代码有效,我在加载多个键的方法中遇到问题。

Well, I had the same problem a year later. 嗯,一年后我遇到了同样的问题。 I wish that you've solved yours. 我希望你解决了你的问题。 I'm writing my solution here just in case that someone else has similar issues. 我在这里写我的解决方案,以防其他人有类似的问题。

Your encryption code doesn't have problem. 您的加密代码没有问题。 The problem might be in the decryption. 问题可能在于解密。 For an encrypted data object, the correct key should be found by using the key id stored with the object. 对于加密数据对象,应使用与对象一起存储的密钥ID找到正确的密钥。 My decryption process reads like the following: 我的解密过程如下所示:

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();
}

The key is the for loop that finds the matching key for the encrypted object. 关键是for循环,它找到加密对象的匹配键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM