java - 使用 BouncyCaSTLe 签署消息摘要

标签 java c# cryptography digital-signature bouncycastle

目前在 C# 中,我正在签署这样的挑战:

RSACryptoServiceProvider rsa;
RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa);
RSAFormatter.SetHashAlgorithm("SHA1");
byte[] SignedHash = RSAFormatter.CreateSignature(paramDataToSign);

然后我将 SignedHash 提供给 Windows,它接受它并且一切正常。但我需要将这部分移动到 Android,但问题是我无法获得相同的签名哈希值。

在 Android 中,我尝试生成签名哈希,但它们与在 C# 中生成的不同。

Signature signer = Signature.getInstance("SHA1withRSA", "BC");
signer.initSign(privateKey);
signer.update(paramDataToSign);
signer.sign();

在 C# 中 - 使用以下代码 - 我得到与在 Android 中相同的结果,但这不是一个选项,因为 Windows 不接受签名的哈希。

ISigner signer = SignerUtilities.GetSigner("SHA1withRSA");
signer.Init(true, privateKey);
signer.BlockUpdate(paramDataToSign, 0, paramDataToSign.Length);
signer.GenerateSignature();

这里写到 C# PKCS1SignatureFormatter 和 Java Signature 应该给出相同的结果,但它们没有。 http://www.jensign.com/JavaScience/dotnet/VerifySig/

可能是什么问题?


这是我得到的 base 64 (WebSafe) 值:

Challenge = zHyz12Tk4m151nssYIBWqBCAxhQ

RSAPKCS1SignatureFormatter SignedHash = kmu39keplCAV4Qnu22wdprLz4nGSsrVtHbxQ5YMUG7p-0YwReCG4ROIlFvYs4CGfjCiAGFPw4PLrLx7mrlAA6iuhJMkgm_PMTW9alQYTH612hLEUP4EmK0M2kw8CveLcjI3HA08z8bByllIzRyAlM8bcR438vw2uhx_CbgvOOHn8vwBPnvWbFqpi2doYoq2xEuFBRe7eBPrxbMRqEd3ExdQ9c9rYT4ivOJ4pbioyi6D5i5_1crvGwM6nQanMZCmooRYJO65NP3B4wWnvQZpJLRD0U08wWcvyGBFWp188ZovDjnkTQZku6lzmwGXfqQwtBz9uNvLcTbp7cVyt5EyQxw

Signature and ISigner SignedHash = Vt-b5QfGPnSPpZuIB8-H4N1K5hQXpImS4e8k56_HruDSqy3DLsz96QKUrccshjr1z9nTK3Mwvd5yPdyTJOqSUcDQqxV46LPhWQNsubqKxAz97ePpeslIH1gHdnzkh46ixsWqgDrhR7egQtDkU8PPsph1qahCxaVkRYspQBV0jPZ-LK4EjoGGnuWTCihVKjruXJZ2VY8yZ9QRAsHVptr0Nv-mldO2MFK-oEVbtVbHqUPf5So8im3oRSm68OqY4g56bCdFNSbhcFBjrZ1QPjnxiIk43-_5tevafqoOB2D_E_mQHCJwmRg3MrNij6IdAdloCejnhCWzgMHdcG1Ug_Qmig

编辑:

所以最简单的解决方案是使用 Bouncy CaSTLe API:

AsymmetricBlockCipher rsaEngine = new PKCS1Encoding(new RSABlindedEngine());
rsaEngine.init(true, privateKey);

DigestInfo dInfo = new DigestInfo(new AlgorithmIdentifier(X509ObjectIdentifiers.id_SHA1, DERNull.INSTANCE), paramDataToSign);
byte[] digestInfo = dInfo.getEncoded(ASN1Encoding.DER);

rsaEngine.processBlock(digestInfo, 0, digestInfo.length);

最佳答案

问题是 RSAFormatter.CreateSignature(paramDataToSign); 传递了哈希值,而 signer.update(paramDataToSign); 传递了数据 散列。因此,您可能必须删除 Java 代码的 MessageDigest 计算才能使其正常工作。

或者,如果您只有散列值,您可以查看 Bouncy CaSTLe 轻量级 API 以找到接受预散列值的方法。这可能可以使用 new RSADigestSigner(new StaticDigest(paramDataToSign, "SHA-1")).generateSignature() 执行。

问题是 StaticDigest 不存在,所以如果你真的需要它,你必须在这里发表评论。或者,镜像 RSADigestSigner 的实现但替换为预先计算的哈希值。

关于java - 使用 BouncyCaSTLe 签署消息摘要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32779216/

相关文章:

java - 反射 getAnnotations() 返回 null

c# - 如何返回一个查询多个表的实体

c# - 实体应该映射到它自己的数据库表吗?

java - 在 JAVA 中检查加密 key 的正确性

c# - 如何从 pem 文件或 xml 文件中读取 RSA 公钥

ListView 和远程数据库中的 java.lang.NullPointerException

java - ScrollPane 不允许向下滚动查看其内容

java - 访问修饰符(公共(public)、私有(private)、内部、 protected )的安全影响

c# - 如何为在 ViewModel 的 DataTemplate 中创建的 View 设置 DataContext

java - 解密加密的 .ser 文件并抛出 StreamCorruptedException