0

我正在处理一个现有系统,它获取十六进制格式的字符串,添加 8 个尾随 0,并使用 gcrypt 对其进行签名。我正在尝试制作一个可以验证签名的 Android 版本。现有系统有效且无法更改。尽管有很多头疼的问题,我还是无法让 android 版本正常工作。

两端就被签名的数据的值、生成的签名的字节以及正在使用的密钥达成一致。我怀疑错误在于对正在签名的数据的解释,我真的不明白。

假设我正在"A5DA123456789B00000000" 用 C++ 签署 linux 端,这样做:

#define FORMAT "(data\n (flags pkcs1)\n (hash sha1 #%s#))\n"
sprintf(blob, FORMAT, "A5DA123456789B00000000");
gcry_sexp_sscan(&keydata, NULL, blob, strlen(blob));

然后将 keydata 作为第二个参数传递给gcry_pk_sign.

android端,在Java中,这样做:

Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(pubkey);
BigInteger bigData = new BigInteger("A5DA123456789B00000000", 16);
sig.update(bigData.toByteArray());
boolean pass = sig.verify();

通过将是错误的。

我可以用 Java 签名,Java 说签名没问题。我们在 linux 中有 C 代码,它说 gcrypt 签名很好。是否有一些我在某处错过的涉及 pkcs1 的晦涩设置?或者我错过了什么明显的东西?有人知道吗?

提前致谢!

4

1 回答 1

0

OK, my thanks to kroot for the significant clue about gcrypt behaviour.

For those that randomly find this question, the problem I had was the code was signing data in a manner which was ... odd ... and not supported by any of the Signature modes in Java. The solution is to user a Cipher object instead. The signature is nothing more than a private-key encrypted hash. To verify it, use the corresponding public key to decrypt the signature and compare the result to the hash of the data being signed.

于 2013-10-21T12:27:13.023 回答