如何在javascript中将字节数组转换为带符号的大整数?

时间:2014-05-30 06:18:39

标签: javascript math biginteger

那里有一些优秀的biginteger.js库。目前我正在使用jsbin.js by Tom Wu在服务器上的浏览和java之间交换匹配的SRP密码证明哈希值。

我的问题是我似乎无法轻易地将表示大型有符号整数的字节数组转换为与下面的Java代码匹配的Javascript BigInteger。这需要能够以匹配两个RFC 5054兼容的java cryto库(bounceycastle和nimbusds)的方式在浏览器中进行散列。两个java库,它们对SRP协议进行H(A,B)散列:

byte[] output = digest.digest(); // sha256 digest gives byte array
return new BigInteger(1, output); // 1 indicates positive number

这不适用于bsbin.js库,因为它没有带有带符号字节数组的构造函数。 Javascript没有签名字节。什么是以与H(A|B)的字节数组构造函数的两个已发布库一起使用的方式对javascript中签名数据进行相同java.math.BigInteger转换的简单方法?

类似下面的内容可以将带符号的字节数组转换为大的十进制字符串:

var output = moduleSHA256.hashToBinaryArray(message); // sha256 digest gives byte array
var signedNumberString = someConversion(output); // ???
return new BigInteger(signedNumberString); // this value toString(16) must match Java code

我也愿意尝试使用不同的javascript BigInteger库,该库具有bsbin.js库的所有数学逻辑,但它具有带符号的字节数组样式构造函数。

N.B。 RFC2945指出将一个字节序列转换为一个大数字是一个关键的实现问题,值得为可互操作的SRP协商指定并指定:

  

n字节字符串S可以转换为整数,如下所示:

     

i = S [n-1] + 256 * S [n-2] + 256 ^ 2 * S [n-3] + ... + 256 ^(n-1)* S [0]

如上所述的问题是Java代码使用BigInteger的字节数组构造函数,它不是平台可移植的,而不是RFC2945中给出的文档转换。

编辑请注意我已经成功编辑了有问题的开源Java加密库,以H(A|B)哈希作为简单的字符串连接,并使所有工作正常,用浏览器交换SRP密码证明但是我不想使用或发布我自己编辑的java加密库版本。我想编写与原始和未经编辑的java SRP加密逻辑兼容的javascript。

编辑请注意一个'修复'是将java更改为十六进制编码由哈希返回的字节数组然后使用构造函数new BigInteger(hexstring,16)更多平台便携式。这将给出与new BigInteger(hashbytes)给出的数字完全不同的数字,但在Javascript中是可重复的,并且在我尝试时也能正常工作。再一次,我不想发布已编辑的java crypo库,所以这是不是解决方案)。

更新我实际上通过在其中一个Java库中使用新的扩展点来插入hash -> hex string -> BigInteger方法来解决这个问题。问题仍然存在,人们想让Javascript像java一样运行,它使用BigInteger的字节数组构造函数。

1 个答案:

答案 0 :(得分:0)

您可以将字节数组转换为十六进制字符串:

// convert a byte (0-255) to a hex string with two characters 'XX'
function dec2hex(value) {
  return (i + 0x100).toString(16).substr(-2).toUpperCase();
}

var hexStr = byteArray.map(dec2hex).join('');

然后将此十六进制字符串加载到像bignumber.js这样的bignumber库中:

var num = new BigNumber(hexStr, 16);