问题描述
使用Signature.verify验证签名时,出现签名无效编码"异常.使用Azure服务验证同一签名时,签名也会得到验证.
When verifying a signature using Signature.verify I receive an "Invalid encoding for signature" exception.When verifying same signature using Azure service, the signature is verified.
我有一个哈希数据(SHA-256),一个公共密钥和一个我要验证的签名.使用com.microsoft.azure.keyvault.KeyVaultClient.sign方法和签名算法"ES256"来接收签名.
I have a hash-data (SHA-256), a public key, and a signature that I'm trying to verify.The signature was received using com.microsoft.azure.keyvault.KeyVaultClient.sign method, with signing algorithm "ES256".
这有效(使用ES256算法):
This works (using ES256 algorithm) :
com.microsoft.azure.keyvault.KeyVaultClient keyVaultClient;
String keyPairIdentifier;
boolean verify(byte[] hashData, byte[] signature, JsonWebKeySignatureAlgorithm signingAlgorithm) {
com.microsoft.azure.keyvault.models.KeyVerifyResult result = keyVaultClient.verify(keyPairIdentifier, signingAlgorithm, hashData, signature);
return result.value().booleanValue();
}
此操作失败(证书拥有与Azure密钥库中存储的相同的公钥):
This fails (certificate holds same public key that is stored in Azure keyvault):
Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
ecdsaSign.initVerify(certificate.getPublicKey());
ecdsaSign.update(hashData);
ecdsaSign.verify(signature)
预期结果-正确(签名已验证)
Expected result - true (signature is verified)
实际结果:
java.security.SignatureException: Could not verify signature
at sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:325)
at java.security.Signature$Delegate.engineVerify(Signature.java:1222)
at java.security.Signature.verify(Signature.java:655)
at TestKV.KeyVault.VerifyDPSignature.verifySignatureUsingCertificate(VerifyDPSignature.java:143)
at TestKV.KeyVault.VerifyDPSignature.main(VerifyDPSignature.java:104)
Caused by: java.security.SignatureException: Invalid encoding for signature
at sun.security.ec.ECDSASignature.decodeSignature(ECDSASignature.java:400)
at sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:322)
... 4 more
Caused by: java.io.IOException: Sequence tag error
at sun.security.util.DerInputStream.getSequence(DerInputStream.java:330)
at sun.security.ec.ECDSASignature.decodeSignature (ECDSASignature.java:376)
推荐答案
dave_thompson_085-谢谢!您所附加的代码中存在一些错误,签名部分的标签应为0x02,而不是0x30,并且在复制第一部分后没有增加o.这是更改后的代码:
dave_thompson_085 - thanks!There were a few mistakes in the code you attached, the tags of the signature parts should be 0x02, not 0x30, and you didn't increase o after copying the first part.This is the code after the changes:
byte[] r = new BigInteger(1,Arrays.copyOfRange(signature,0,32)).toByteArray();
byte[] s = new BigInteger(1,Arrays.copyOfRange(signature,32,64)).toByteArray();
byte[] der = new byte[6+r.length+s.length];
der[0] = 0x30; // Tag of signature object
der[1] = (byte)(der.length-2); // Length of signature object
int o = 2;
der[o++] = 0x02; // Tag of ASN1 Integer
der[o++] = (byte)r.length; // Length of first signature part
System.arraycopy (r,0, der,o, r.length);
o += r.length;
der[o++] = 0x02; // Tag of ASN1 Integer
der[o++] = (byte)s.length; // Length of second signature part
System.arraycopy (s,0, der,o, s.length);
更改格式后,我没有收到序列标签错误"异常.但是验证仍然失败.
After the format change I didn't get the "Sequence tag error" exception. But the verification still failed.
谢谢!
这篇关于java.security.SignatureException:签名的无效编码.由Azure验证的签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!