java - 如何使用 BouncycaSTLe PGPContentSigner 对字节数组进行清除签名?

标签 java bouncycastle pgp

我正在尝试使用 bouncycaSTLe 版本 1.49 中未弃用的构造函数,但我很难弄清楚如何使用这些创建的对象,因为它与我之前的任何教程都有点不同网上查到的。

这是我到目前为止的代码;谁能告诉我应该如何处理 PGPContentSigner 以及如何将其连接到 OutputStream?我想要实现的是在数据上附加签名,而无需将数据加密给任何特定的人(很像 gpg --clearsign -a <textfile> )。

我调查过ArmoredOutputStream及其方法,beginClearText(int)看起来很有希望,但只是调用它,将数据转储到输出流中,调用 endClearText ,然后将签名字节写入 ArmoredOutputStream不起作用。看起来好像需要对流进行低级操作,将控制字节插入流中以表示签名的开始,等等。在我看来,应该有某种固定装置来 Hook 签名者和签名者。铠装输出流在一起,可以处理数据包的杂耍。

/**
 * Generate a signature for the given bytes so that they can be sent off and the recipient can verify
 * that the bytes have not been tampered with in transit.
 *
 * @param dataBytes the data to sign
 * @return the data along with the signature
 * @throws PGPException if there's a problem generating the signature
 */
public static byte[] clearSignBytes(byte[] dataBytes, PGPSecretKeyRingCollection skrCollection, String keyPass) throws PGPException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); // this is where we put the signed data

    try {
        // get our secret key so we can init the signature generator
        Iterator<PGPSecretKeyRing> it = skrCollection.getKeyRings();
        PGPSecretKeyRing skr = it.next();
        PGPSecretKey skey = skr.getSecretKey();
        PGPPrivateKey prKey = skey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(keyPass.toCharArray()));
        BcPGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder(skey.getPublicKey().getAlgorithm(), PGPUtil.SHA256);
        PGPContentSigner signer = signerBuilder.build(PGPSignature.BINARY_DOCUMENT, prKey);

        // Now, we're supposed to write dataBytes somewhere and we're supposed to hand them to the signer somehow
        // and ultimately we're supposed to tell the signer to output a signature and we put the signature and
        // dataBytes together into baos.
        // TODO ??????
    } catch (Exception e) {
        __l.error("Exception generating signature", e);
        throw new PGPException("Exception while signing the data", e);
    }
    return baos.toByteArray();
}

最佳答案

事实证明我没有使用正确的类来完成工作。这是该方法的相关部分,其中包含实际有效的代码。我希望这可以帮助其他有同样困惑的人。在我们获得 PGGPrivateKey prKey 后...

        PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(skey.getPublicKey().getAlgorithm(), PGPUtil.SHA256).setProvider("BC"));
        PGPSignatureSubpacketGenerator  spGen = new PGPSignatureSubpacketGenerator();

        sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, prKey);
        Iterator userIDs = skey.getPublicKey().getUserIDs();
        if (it.hasNext()) {
            spGen.setSignerUserID(false, (String)userIDs.next());
            sGen.setHashedSubpackets(spGen.generate());
        }

        ArmoredOutputStream aos = new ArmoredOutputStream(baos);
        aos.beginClearText(PGPUtil.SHA256);

        sGen.update(dataBytes);
        aos.write(dataBytes);

        aos.endClearText();

        BCPGOutputStream bOut = new BCPGOutputStream(aos);
        sGen.generate().encode(bOut);

        aos.flush();
        aos.close();

关于java - 如何使用 BouncycaSTLe PGPContentSigner 对字节数组进行清除签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18772283/

相关文章:

java - 具有不同大小的 ActionBar 图标

java - 在 Java 中登录 - 每次变量更改时自动转储变量值的任何方式

java - 禁用注释处理,但在 servlet api 3.0 (Tomcat7) 中启用 web-fragments 功能

java - Java 中 Bouncy CaSTLe 的性能

java - 有没有一种方法可以在没有代码生成的情况下编写原型(prototype)数据?

java - 将 BouncyCaSTLe 与 GnuPG 2. 1's ` pubring.kbx` 文件一起使用

java - Java 加密扩展的 key 长度限制

node.js - 使用加密库在 NodeJS 中创建 PGP 兼容签名

automation - 如何在不手动执行的情况下信任一堆您信任的公共(public) pgp key ?

ruby-on-rails - 安装 RVM(Ruby 版本管理器)的关键问题