我在使用SHA-256算法和NIST P-256类型密钥验证Java中的签名时遇到了问题。
我有一个X509证书(由证书颁发机构提供),其中包含一个公钥,我应该证明我收到的消息的真实性。
我收到的签名用Base32编码(103个字符),我将其解码为二进制。我获得了一个64字节的字节数组。
关于公钥的信息:
Sun EC public key, 256 bits
public x coord: 76693623628200764797317561328856095594448010045454057728566183687964056347177
public y coord: 111784915166853162657631137717721670318464358783507947441022826650722573271612
parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)
(编辑)我用来验证邮件真实性的方法:
public static void verify(String message, String signatureReceived, String pathToCertificate) {
try {
final X509Certificate certificat = getCertificate(pathToCertificate);
final PublicKey publicKey = certificat.getPublicKey();
final byte[] signatureReceivedInBinary = BaseEncoding.base32().decode(signatureReceived);
byte[] rBytes = Arrays.copyOfRange(signatureReceivedInBinary, 0, 32);
byte[] sBytes = Arrays.copyOfRange(signatureReceivedInBinary, 32, 64);
BigInteger r = new BigInteger(1, rBytes);
BigInteger s = new BigInteger(1, sBytes);
ASN1Integer asn1R = new ASN1Integer(r);
ASN1Integer asn1S = new ASN1Integer(s);
DERSequence seq = new DERSequence(new ASN1Integer[]{asn1R, asn1S});
byte[] encoded = seq.getEncoded();
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initVerify(publicKey);
signature.update(message.getBytes("UTF-8"));
if (signature.verify(encoded)) {
System.out.println("Signature OK");
} else {
System.out.println("Signature KO");
}
} catch (Exception e) {
e.printStackTrace();
}
}
主要课程:
public static void main(String[] args)
throws NoSuchAlgorithmException, CertificateException, IOException,
KeyStoreException {
final String message = "MessageToValidate";
final String certificatPath = "<PATH_TO_CERTIFICATE>\\public_certificat.crt";
final String signature = "UBFF4NY7MIXQVUZYMRDRGXBTVWIVMCNP76TN7SA24QUJ4AAHG4WTLA2QZ5TSC54F2OQRMWOAKSHLXJLNHXH4GJPBHBWXBO3PMSDOVZI";
try {
Test.verify(message, signature, certificatPath);
} catch (final Exception e) {
System.out.println(e.getMessage());
}
}
当我执行我的应用程序时,我收到此错误:
Exception in thread "main" java.security.SignatureException: Could not verify signature
at sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:325)
at java.security.Signature$Delegate.engineVerify(Signature.java:1219)
at java.security.Signature.verify(Signature.java:652)
at fr.altes.music.utils.Test.verify(Test.java:56)
at fr.altes.music.Application.main(Application.java:54)
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)
... 5 more