【发布时间】:2018-07-18 10:29:14
【问题描述】:
问题:如何在 Java 中转换 BigInteger 以匹配 Botan BigInt 编码?
我使用 Botan 在 Java 和 C++ 应用程序之间进行通信。 Botan 有一个 BigInt 类,与 BigInteger 相当。但是,转换为字节数组时,编码会有所不同。
在 Botan 中,BigInt 编码如下:
void BigInt::binary_encode(uint8_t output[]) const
{
//bytes just returns the # of bytes, in my case its 32 always
const size_t sig_bytes = bytes();
for(size_t i = 0; i != sig_bytes; ++i)
output[sig_bytes-i-1] = byte_at(i);
}
在 Java 中,它的编码:
public byte[] toByteArray() {
int byteLen = bitLength()/8 + 1;
byte[] byteArray = new byte[byteLen];
for (int i=byteLen-1, bytesCopied=4, nextInt=0, intIndex=0; i >= 0; i--) {
if (bytesCopied == 4) {
nextInt = getInt(intIndex++);
bytesCopied = 1;
} else {
nextInt >>>= 8;
bytesCopied++;
}
byteArray[i] = (byte)nextInt;
}
return byteArray;
}
【问题讨论】:
-
标题错误。目前想不出更好的,但它会吸引巨魔。我能想到的最好的事情是序列化为中性编码,然后将其读回特定编码。对于愚蠢的概念证明,我会使用一串 ASCII 数字。
-
Javadocs 非常仔细和准确地描述了
BigInteger.toByteArray()的输出。博坦呢? -
在每个系统上都有来自相同输入的样本输出会更有用,这样我们就可以给你一个有意义的答案。我知道我无法使用 Botan 进行测试。正如@matt 所建议的那样,事情可能会因为 Java 没有无符号数据类型而被抛弃。
-
您要序列化的整数是负数吗? Java 在编码时使用 2s 补码表示,而 Botan 在编码时有效地忽略符号,编码绝对值。对于非负整数,Botan 应该毫无问题地解码 Java 的 toByteArray 的输出。另一个可能的问题是,Java 还假设 byte[] 构造函数的输入是 2s 补码。因此,如果您在 Botan 中使用设置的高位对整数进行编码,它将输出一个设置了前导 1 位的数组。 Java 会将其解释为负整数。使用 0x00 字节的前缀来解决这个问题。
标签: java c++ encryption biginteger botan