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

时间:2015-08-10 11:32:30

标签: java encryption biginteger

Java:jre1.8.0_45

我完成了Elliptic Curve类的调试并记录了键的所有特征,我还记录了键的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位,但也不时有几位关闭。所以它与Elliptic Curve中的奇数位无关。

经过长时间的搜索,我认为我找到了一个解释,或者至少是一个解释的开头,但我不知道这是预期还是Java Bug。

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

  

0x27006F59EA138FE01FBE1F554253DBDD84D73719E77088907357C6FA6B60F170

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

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

我想知道这是否是BigInteger.bitLength()的WANTED行为,或者这可能是一个错误。我不会问这个问题是不是我认为Java中的许多加密代码可能依赖于BigInteger(包括提供者)而我无法想象他们不会遇到这个问题。

TIA

1 个答案:

答案 0 :(得分:2)

它按预期和记录的方式工作。

来自documentation

  

返回此BigInteger的最小二进制补码表示中的位数,不包括符号位。对于正BigIntegers,这相当于普通二进制表示中的位数。

注意这里的“最小”部分 - 例如,十进制值5可以表示为00000000000000000000000000101或101 ...但101是最小表示,因此位长度为3.