Bouncy Castle PGP 一次性签名和加密?

Bouncy Castle PGP sign and encrypt in one pass?

我正在寻找 Bouncy Castle PGP 'sign and encrypt' 的实现。理想情况下,在一次操作中,如果这有什么不同的话。

我已经采用 encrypt example and the signing example 并尝试将其变成 'one pass' 加密和签名操作。

我看到这个相对过时的实现 Boncode。这似乎表明这两个操作只是联系在一起。

我不会让消费者解密代码。签名似乎可以验证。无论我使用合并操作还是单独加密然后签名都是如此。

是否有更好的 Bouncy Castle PGP 实现?

这是我目前的一个单通道实现,Bouncy Castle PGP 加密+签名。签名好像可以验证,但是payload没有解密

public class SinglePassSignedEncryptedFileProcessor {
private static final Logger logger = LoggerFactory.getLogger(SinglePassSignedEncryptedFileProcessor.class);

/*
 * This is the primary function that will create encrypt a file and sign it
 * with a one pass signature. This leans on an C# example by John Opincar
 * @author Bilal Soylu
 * @param targetFileName
 *            -- file name on drive systems that will contain encrypted content
 * @param embeddedFileName
 *            -- the original file name before encryption
 * @param secretKeyRingInputStream
 *            -- Private Key Ring File
 * @param targetFileStream
 *            -- The stream for the encrypted target file
 * @param secretKeyPassphrase
 *            -- The private key password for the key retrieved from
 *            collection used for signing
 * @param signPublicKeyInputStream
 *            -- the public key of the target recipient to be used to
 *            encrypt the file
 * @throws Exception
 */
public void encryptOnePassSign(
        String fileName,
        InputStream keyIn,
        OutputStream out,
        char[] pass,
        PGPPublicKey encryptionKey,
        boolean armor,
        boolean withIntegrityCheck,
        String providerName)
        throws IOException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException {
    if (armor) {
        out = new ArmoredOutputStream(out);
    }

    // Compress
    byte[] bytes = PGPEncryptUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);

    // Encryption process.
    PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
            new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));

    encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encryptionKey).setProvider("BC"));

    ByteArrayOutputStream encryptedOutputStream = new ByteArrayOutputStream();
    OutputStream encryptedOut = encGen.open(encryptedOutputStream, bytes);
    encryptedOut.write(bytes);
    encryptedOut.close();
    byte[] bytesEncrypted = encryptedOutputStream.toByteArray();
    encryptedOutputStream.close();

    // Signing process.
    PGPSecretKey pgpSec = PGPEncryptUtil.readSecretKey(keyIn);
    PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));

    PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));

    sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);

    Iterator it = pgpSec.getPublicKey().getUserIDs();
    if (it.hasNext()) {
        PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();

        spGen.setSignerUserID(false, (String) it.next());
        sGen.setHashedSubpackets(spGen.generate());
    }

    PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
            PGPCompressedData.UNCOMPRESSED);

    // Write to the output stream.
    BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out));
    sGen.generateOnePassVersion(false).encode(bOut);

    File file = new File(fileName);
    PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
    // file is encoding name.
    Date lastModified = new Date(file.lastModified());
    OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, fileName, lastModified, bytesEncrypted);


    //FileInputStream fIn = new FileInputStream(file);
    //int ch;

    //while ((ch = fIn.read()) >= 0) {
        lOut.write(bytesEncrypted);
        sGen.update(bytesEncrypted);
   // }

    // ?
    lGen.close();

    sGen.generate().encode(bOut);
    cGen.close();

    if (armor) {
        out.close();
    }
    // close everything down we are done
    /*
    literalOut.close();
    literalDataGenerator.close();
    signatureGenerator.generate().encode(compressedOut);
    compressedOut.close();
    compressedDataGenerator.close();
    encryptedOut.close();
    encryptedDataGenerator.close();
     */

    // if (armor) targetFileStream.close();

}
}

最新答案是使用BouncyGPG

按照测试用例工作。科特林

  val encryptionStream = BouncyGPG
            .encryptToStream()
            .withConfig(keyringConfig)
            .withStrongAlgorithms()
            .toRecipient("recipient@example.com")
            .andSignWith("sender@example.com")
            .armorAsciiOutput()
            .andWriteTo(cipherText)

    encryptionStream.write(expectedPlaintext)
    encryptionStream.close()
    cipherText.close()