简体   繁体   中英

My code can verify self signed certificate but is failing when VeriSign issued certificate is used

My application is using java security APIs to sign a file and verify it. While signing , I am using PFX file and password as inputs and after signing I am generating a signature file using the bytes. While verification process I am using signature file ,certificate file and the signed file as inputs. Please find the code I am using in verification below:

 // KeyFilePath= path of certificate file
 // fileToVerify = path of signed file
 // signatureFilePath = path of signature file



 InputStream inputStream = new FileInputStream(KeyFilePath);
 CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
 X509Certificate x509Certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);

 // input the signature bytes
 String sigFile = signatureFilePath;

 FileInputStream sigFileInputStream = new FileInputStream(sigFile);
 byte[] sigToVerify = new byte[sigFileInputStream.available()];
 sigFileInputStream.read(sigToVerify);
 sigFileInputStream.close();

 PublicKey pubKey = x509Certificate.getPublicKey();
 Signature signature = Signature.getInstance(signAlgorithm);

 signature.initVerify(pubKey);

 // Update and verify the data
 try {
    FileInputStream dataFileInputStream = new FileInputStream(fileToVerify);
    BufferedInputStream bufferedInputStream = new BufferedInputStream(dataFileInputStream);

    byte[] buffer = new byte[IVerifyDigitalSignature.BYTE_SIZE];
    int bufferedInputStreamLength;

    while (bufferedInputStream.available() != IVerifyDigitalSignature.ZERO_LENGTH) {
        bufferedInputStreamLength = bufferedInputStream.read(buffer);
        signature.update(buffer, IVerifyDigitalSignature.ZERO_LENGTH, bufferedInputStreamLength);
    }

    bufferedInputStream.close();

    // Verify the Signature
    x509Certificate.verify(pubKey);
    verifyDigitalSignature = signature.verify(sigToVerify);

Please help me in resolving the same as it is yet not closed.

If you want to do this yourself, yes you must iterate over the certs in the chain from a trust anchor to your desired cert, however long that it is (it may vary for different CAs, classes, and at different times). Verifying the signature on each "child" (lower level) cert using the publickey from the "parent" (next higher) cert is only a fairly small part of this; there are many other steps needed. Often just finding the right certs can be an issue; if you already have a correct chain you have a head start. But are you sure you have "the" right chain? Frequently there are several possible chains for a given cert, and sometimes some of them are valid but others have expired or become unverifiable. Verisign in particular issued I believe all recent certs under their G5 root but provided an alternate path back to (effectively) G1 for reliers that aren't up to date, and sometimes can't be updated.

The algorithm for most situations is defined in "PKIX" RFC5280 , except that OCSP RFC6960 instead of CRL for revocation is becoming more common. You might get away with omitting cross-hierarchy and NameConstraints, which AFAIK aren't actually used by public CAs like Verisign, and the Policy stuff which CAs do use but users/reliers don't care about. https://security.stackexchange.com/questions/37409/certificate-chain-checking has a good but not complete introduction.

But you're probably better off using Java's (really JCE's) CertPathValidator for "PKIX" -- and if needed CertPathBuilder -- to which I already referred you. This has already been written and tested by experts. Just calling it is still a little bit complicated, but nowhere near as complicated as rewriting all the things it does.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM