给出一个人的X509证书对象。 (对象的类型为sun.security.x509.X509CertImpl)。此人用他的私钥在字符串上签名。给定此人在签名上述String对象时所做出的签名。
我的任务是验证此签名,但遇到困难。
当我尝试使用以下代码验证签名时:
...
X509Certificate x509Certificate = getCertificate(certificate);
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initVerify(x509Certificate.getPublicKey());
signature.update(unsignedData);
boolean bool = signature.verify(signatureToVerify);
System.out.println("The signature is " + (bool ? "" : "NOT") + " valid");
我得到java.security.SignatureException: Could not verify signature
您有一个主意,我如何使它起作用?
已编辑: 最后,我设法使其正常运行,但尚不了解原因: 在将签名传递给verify方法之前,我需要对其进行以下修改:
byte[] rBytes = Arrays.copyOfRange(signatureHash, 0, 32);
byte[] sBytes = Arrays.copyOfRange(signatureHash, 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[] signatureToVerify2 = seq.getEncoded();
// verifying the signatureToVerify2 instead of the original brings success
boolean bool = signature.verify(signatureToVerify2);
答案 0 :(得分:0)
这是一个(半)工作的应用程序,用于在故事涉及ECDSA时验证签名的进一步参考:
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.DERSequence;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
public class SignatureTest {
public static void main(String[] args) throws CertificateException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, IOException {
byte[] certificateAsByteArray = ...;
byte[] dataToVerifyAsByteArray = ...;
byte[] signatureHashAsByteArray = ...;
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(certificateBytes);
X509Certificate x509Certificate = (X509Certificate) certFactory.generateCertificate(in);
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initVerify(x509Certificate.getPublicKey());
signature.update(dataToVerifyAsHexaString);
byte[] rBytes = Arrays.copyOfRange(signatureHash, 0, 32);
byte[] sBytes = Arrays.copyOfRange(signatureHash, 32, 64);
ASN1Integer asn1R = new ASN1Integer(rBytes);
ASN1Integer asn1S = new ASN1Integer(sBytes);
DERSequence seq = new DERSequence(new ASN1Integer[] {asn1R, asn1S});
boolean isSignatureOK = signature.verify(seq.getEncoded());
System.out.println("The signature is " + (isSignatureOK ? "" : "NOT ") + "VALID");
}
}