如果公钥的算法是EC,如何在Java中验证签名?

萨沃

给定一个人的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);
萨沃

当故事涉及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");
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章