Java ECC ASN1签名验证失败
我有48字节的ECC secp192r1签名,在其他环境下工作:Java ECC ASN1签名验证失败,java,cryptography,digital-signature,bouncycastle,elliptic-curve,Java,Cryptography,Digital Signature,Bouncycastle,Elliptic Curve,我有48字节的ECC secp192r1签名,在其他环境下工作: byte[] signature = new byte[]{(byte)0x08, (byte)0x33, (byte)0x6B, (byte)0x27, (byte)0xBC, (byte)0x29, (byte)0x64, (byte)0x36, (byte)0x70, (byte)0x08, (byte)0x97, (byte)0x4F, (byte)0xA8, (byte)0xD7, (byte)0x1F, (byte)0
byte[] signature = new byte[]{(byte)0x08, (byte)0x33, (byte)0x6B, (byte)0x27, (byte)0xBC, (byte)0x29, (byte)0x64, (byte)0x36, (byte)0x70, (byte)0x08, (byte)0x97, (byte)0x4F, (byte)0xA8, (byte)0xD7, (byte)0x1F, (byte)0x4D, (byte)0x05, (byte)0xF5, (byte)0xB2, (byte)0x0F, (byte)0x15, (byte)0x5D, (byte)0x68, (byte)0x61, (byte)0xB3, (byte)0x2B, (byte)0x0E, (byte)0xA9, (byte)0xFB, (byte)0x37, (byte)0xF1, (byte)0xD4, (byte)0x70, (byte)0xEA, (byte)0x2B, (byte)0xCA, (byte)0x53, (byte)0x9D, (byte)0x11, (byte)0xE7, (byte)0x26, (byte)0x37, (byte)0x92, (byte)0x73, (byte)0xDE, (byte)0x95, (byte)0x6C, (byte)0x4A};
它被编码为ASN1格式,长度为54字节,具有:
byte[] sig1 = Arrays.copyOfRange(signature, 0, 24);
byte[] sig2 = Arrays.copyOfRange(signature, 24, 48);
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1Integer(new BigInteger(sig1)));
v.add(new ASN1Integer(new BigInteger(sig2)));
byte[] javaSig = new DERSequence(v).getEncoded();
然而,当我尝试验证数据时,它失败了。将签名编码为ASN1是否正确
从ASN1到48字节格式的签名解码也存在同样的问题:
ASN1InputStream input = new ASN1InputStream(signed);
ASN1Primitive item = input.readObject();
ASN1Sequence s = (ASN1Sequence)item;
BigInteger[] items = new BigInteger[2];
items[0] = ((ASN1Integer)s.getObjectAt(0)).getValue();
items[1] = ((ASN1Integer)s.getObjectAt(1)).getValue();
byte[] itBytes0 = items[0].toByteArray();
byte[] itBytes1 = items[1].toByteArray();
从
byte[]
创建biginger
时的一个常见问题是,在Java上,默认情况下,所有数字都被解释为单号:
biginger(byte[]val)
将包含BigInteger的二元补码二进制表示形式的字节数组转换为BigInteger
我不知道您使用的算法是否需要一个有符号或无符号的数字,但是,显式地强制Java将字节数组解释为无符号数字是值得的:
v.add(new ASN1Integer(new BigInteger(1, sig1)));
v.add(new ASN1Integer(new BigInteger(1, sig2)));
从
byte[]
创建biginger
时的一个常见问题是,在Java上,默认情况下,所有数字都被解释为单号:
biginger(byte[]val)
将包含BigInteger的二元补码二进制表示形式的字节数组转换为BigInteger
我不知道您使用的算法是否需要一个有符号或无符号的数字,但是,显式地强制Java将字节数组解释为无符号数字是值得的:
v.add(new ASN1Integer(new BigInteger(1, sig1)));
v.add(new ASN1Integer(new BigInteger(1, sig2)));
使用ECDSA从ECDSA切换到非ECDSA:
Signature sig = Signature.getInstance("NONEwithECDSA", "BC");
使用ECDSA从ECDSA切换到非ECDSA:
Signature sig = Signature.getInstance("NONEwithECDSA", "BC");
它有助于创建公钥,但不影响签名验证。它有助于创建公钥,但不影响签名验证。