我使用不推荐的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);
答案 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