1

我正在使用 secp256r1 曲线和使用 BouncyCastle 的 SHA256 算法实现 ECDSA 签名生成。

对于某些输入,签名长度为 127 个字符。我觉得开头的“0”正在被删除,因为签名存储在 ECDSASigner 类中的 BigInteger 数据类型中。

使用确定性方法添加了来自 rfc6979 ECDSA 签名的样本

代码的相关部分: -

//Private key used in hex format -C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721
        String secretNumberK = "09F634B188CEFD98E7EC88B1AA9852D734D0BC272F7D2A47DECC6EBEB375AAD4";
        SecureRandom secureRandom = new FixedSecureRandom(Hex.decode(secretNumber));
        ECPrivateKeyParameters ecPrivateKeySpec = Util.getECPriKeyParameter(ecPrivateKey);//it is the PrivateKey of the sample shown 
        byte[]  messageInHex = Hex.decode("test");
        
         ECDSASigner ecdsaSigner = new ECDSASigner();

        ecdsaSigner.init(true, new ParametersWithRandom(ecPrivateKeySpec,
                secureRandom));

         BigInteger[]  sig = ecdsaSigner.generateSignature(Util
                .generateSHAHash(messageInHex));
        flag = true;
        LOG.debug("r:: " + sig[0].toString(16).toString());
        LOG.debug("s:: " + sig[1].toString(16).toString());

根据文件的预期签名 R 和 S:-

 r = 0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719
 s = 4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954

但我得到

r = EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719
s = 4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954

唯一的区别是 r 值为零。由于这个签名长度只有 127。

请让我知道我的推断是否正确。这是Bouncy Castle中的错误吗?

4

1 回答 1

5

这不是 BouncyCastle 中的错误。BouncyCastle 已向您返回一个 BigInteger。我不相信 Java 的 BigInteger 类存储有关应该打印多少前导零的任何信息,并且您在使用时没有提供该信息.toString(16).toString(),因此不可避免的结果是不会显示前导零。

你明白,例如,十六进制“0EAF”与十六进制“EAF”是相同的数字,对吧?所以这只是一个字符串格式问题。数字是正确的。

如果您希望字符串与文档中的文本完全匹配,则在格式化字符串时需要做一些额外的工作以添加前导零。

这是一个类似的问题和资源:

于 2015-07-09T20:50:27.193 回答