用充气城堡验证签名

时间:2014-06-27 12:22:18

标签: java bouncycastle signing

我使用不推荐的bouncycastle API继承了一些代码。在将其更新为新API之前,我想编写一个测试来验证我没有更改其行为。但是,我无法确定正确的方法来验证生成的此签名。要更改的代码是:

public static byte[] createSignedData(byte[] content, X509Certificate cert, PrivateKey key)
        throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, IOException {

    // set up the generator
    CMSSignedDataGenerator gen = new CMSSignedDataGenerator();

    gen.addSigner(key, cert, CMSSignedGenerator.DIGEST_SHA1);

    // create the signed-data object
    CMSProcessable data = new CMSProcessableByteArray(content);
    CMSSignedData signed = gen.generate(data, BC_PROVIDER);

    return signed.getEncoded();
}

此代码返回了什么内容?一个独立的签名? 我尝试用这样的一小段代码验证签名,但它总是返回false:

Signature signer = Signature.getInstance(
                              "SHA1withRSA", 
                              BouncyCastleProvider.PROVIDER_NAME);
signer.initVerify(cert.getPublicKey());
signer.update(data);
return signer.verify(sig);

1 个答案:

答案 0 :(得分:2)

如果您使用以下内容,它将返回 分离的 签名:

gen.generate(data, false);

否则,它将返回封装在签名 中的 签名数据。因此,如果您的签名已分离(这不是您的情况),为了验证它,您需要从签名数据字节或CMSSignedData创建新的Base64对象enconded string以及原始数据的副本以及构造函数。

我认为您没有以正确的方式验证您的签名,我也不知道您使用的是哪个bouncycastle库版本,而您只是提供了一个过于模糊而无法分析的代码段。

这是我使用 bcmail-jdk16-1.46.jar bcprov-jdk16-1.46.jar {{1}签署和验证签名所做的工作(我假设您使用的是 Java ,因为您从未指定它,也有问题标签 - 但希望 .NET 版本非常相似)。< / p>

您可以下载我的示例中使用的 密钥库 https://dl.dropboxusercontent.com/u/15208254/keys/certificates.p12

此外,如果您想检查签名验证是否正常,您可以更改证书(因为我正在验证我自己的证书,这是没有意义的)签名验证过程中的行 第84行

jdk1.6.0_45

然后加载另一个 密钥库 以从中获取另一个 证书 。要知道,我正在使用的 certificates.p12 文件包含两个带有别名if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC_PROVIDER).build(certFromSignedData))) { ... } Key1的证书,因此您可以使用它们使用Key2对您的内容进行签名,然后使用Key1验证您的签名。

<强> e.g:

Key2

然后将 第84行 替换为:

// Load 'Key2' certificate from 'certificates.p12' at any place on this class after 'ks' declaration
X509Certificate certFromKeystore2 = (X509Certificate) ks.getCertificate("Key2");

请注意,if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC_PROVIDER).build(certFromKeystore2))) { ... } 已更改为certFromSignedData,您的签名验证将失败,因为您的内容已使用certFromKeystore2签名。


Java代码:

不要忘记更改常量中的密钥库路径!

Key1