1

我有一个数字签名 ( byte[] signedBytes) 在byte[] array. 我需要将其转换为BigInteger( bigSignedBytes),将生成的数字用于某事,然后byte[] convertBackSignedBytesBigInteger.

byte[] signedBytes = rsa.sign();
BigInteger bigSigned = new BigInteger(signedBytes);
convertBackSignedBytes = bigSigned.toByteArray();
//signedBytes and convertBackSignedBytes differ.

问题是在从BigIntegerback to重新转换之后byte[] convertBackSignedBytes- 它似乎与我的原始signedBytes变量不同。我知道BigInteger.toByteArray()返回一个二进制补码byte[] value- 这可能是负责任的。

那么如何在BigInteger没有二进制补码的情况下获取原始字节呢?

有人推荐这个:

byte[] convertBackSignedBytes = bigIntegerValue.toByteArray();
if (convertBackSignedBytes[0] == 0) {
    byte[] tmp = new byte[convertBackSignedBytes.length - 1];
    System.arraycopy(convertBackSignedBytes, 1, tmp, 0, tmp.length);
    convertBackSignedBytes = tmp;
}   

试过了 - 没用。仍然从 original 返回不同的 byte[]value signedBytes

如果我尝试验证原始签名 - 它会成功。

但是,如果我尝试使用转换后的签名进行验证 - 它会失败。所以signedBytesconvertBackSignedBytes不再一样。

请问有什么快速的指点吗?

4

2 回答 2

1

如果二进制补码确实是问题(我不相信),您应该能够通过始终在原始字节数组之前添加一个 0x00 字节来解决它。这样,您将始终拥有一个正数。

但是,例如,这可能是问题所在:如果您的原始数组以 0x00 或 0xFF 字节开头,则它们中的一些或全部可能会在转换过程中消失。

因此,您为什么不简单地传输像“0102affe01dead07cafe89babe”这样的字符串,而不是传输一个整数?将字节编码为十六进制字符串并返回应该很简单。

如果您绝对必须使用大整数,请在编码前添加 0x01(这仍会给出正数)并在解码后将其删除。

于 2013-02-23T21:25:14.997 回答
0

由于长度不同,转换回可能会失败。

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class So15045472 {
    static void print(byte[] bytes) {
        List<Byte> bs=new ArrayList<Byte>(bytes.length);
        for(byte b:bytes)
            bs.add(b);
        System.out.println(bs);
    }
    static boolean compare(byte[] x,byte[] y) {
        if(x.length!=y.length) {
            System.out.println("unequal lengths");
            return false;
        }
        for(int i=0;i<x.length;i++)
            if(x[i]!=y[i])
                return false;
        return true;
    }
    static void check(byte[] bytes) {
        BigInteger x=new BigInteger(bytes);
        System.out.println(x);
        byte[] b=x.toByteArray();
        print(bytes);
        print(b);
        boolean isEqual=compare(bytes,b);
        if(!isEqual)
            System.out.println("compare says "+isEqual);
        else System.out.println("ok");
    }
    public static void main(String[] args) {
        byte[] b1=new byte[]{(byte)0x00,(byte)0xff};
        check(b1);
        byte[] b2=new byte[]{(byte)0xff,(byte)0xff};
        check(b2);
    }
}
于 2013-02-23T21:37:19.770 回答