使用 secp256r1 曲线 (BouncyCastle) 生成长度为 127 的签名的 ECDSA 签名

ECDSA signature generation using secp256r1 curve (BouncyCastle) giving signature with length 127

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

对于某些输入,签名长度为 127 个字符。我觉得开头的“0”被删除了,因为签名存储在 ECDSASigner class.

中的 BigInteger 数据类型中

我添加了来自 rfc6979 的示例 ECDSA signing using Deterministic Approach

代码的相关部分:-

//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.

请告诉我我的推断是否正确。这是充气城堡中的错误吗?

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

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

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

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