Java BigInteger bitLength() 方法忽略前导 0 位

Java BigInteger bitLength() method ignores leading 0-bits

Java : jre1.8.0_45

我完成了椭圆曲线的调试 class,在记录密钥的所有特征时,我还记录了密钥的 BIT 长度(椭圆曲线的比特长度并不总是偶数)。

我通过 BigInteger 显示密钥的位长度:

ECPrivateKey oPK=generate the key ...
BigInteger oBI=oPK.getS(); 
MetaLogBook.debug("Key Size in Bits :"+oBI.bitLength()+
                "\nRaw Key Hex      : 0x"+oBI.toString(16)).toUpperCase()+"\n"+);

虽然密钥始终正确表示并且加密工作正常,但位大小却会波动。很多时候它是正确的 (571),但有时会出现偏差。

所以我开始生成 AES-256 密钥,我注意到它们通常是 256 位,但有时也会偏离几位。所以跟椭圆曲线的奇数位无关

经过长时间的搜索,我想我找到了解释,或者至少是解释的开始,但我不知道这是有意为之还是 Java 错误。

当我看到这个 64 字节的十六进制(32 字节 AES 256 位密钥)的位长度显示为 254 而不是 256 时,我可以得出结论。

0x27006F59EA138FE01FBE1F554253DBDD84D73719E77088907357C6FA6B60F170

最后一个半字节是 0,所以如果不计算尾随 0 位,那么我在 bitLength() 中至少少了 4 位,而我只少了 2 位。

然后我想到我的密钥的第一个半字节以 2 或二进制 0010 开头。所以我认为 BigInteger.bitLength() 没有计算前导零位。我重复了很多次,行为似乎是一致的(通常我认为每个人都可以重现)。

我想知道这是否是 BigInteger.bitLength() 的预期行为,或者这是否可能是一个错误。如果不是我假设 Java 中的许多加密代码可能依赖于 BigInteger(包括提供商),我不会问这个问题,我无法想象他们不会 运行问题。

TIA

它按预期和记录工作。

来自documentation

Returns the number of bits in the minimal two's-complement representation of this BigInteger, excluding a sign bit. For positive BigIntegers, this is equivalent to the number of bits in the ordinary binary representation.

请注意此处的 "minimal" 部分 - 例如,十进制值 5 可以表示为 00000000000000000000000000101 或 101...但是 101 是最小表示,因此位长度为 3。