Android验证X.509证书中的CA签名

时间:2015-12-03 03:30:43

标签: java android digital-signature ecdsa spongycastle

我有一个根CA证书和一个由CA签名的用户证书。在使用Certutil或OpenSSL的Windows下,我可以验证用户证书签名上的CA签名是否正常。现在我想在Android下验证相同的签名。

我使用的是Spongy Castle,虽然我不确定这一步是否完全必要。我使用ECDH 384位密钥对。签名是“SHA384WITHECDSA”。我可以生成自签名证书并通过certificate.verify方法或通过计算签名来验证其签名:

public static byte[] GenerateMyClientCertificate()
            throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException
    {
        // Create the keys
        KeyPairGenerator ClientkeyPair = KeyPairGenerator.getInstance("ECDH", "SC");
        ECGenParameterSpec ecParamSpec2 = new ECGenParameterSpec("P-384");
        ClientkeyPair.initialize(ecParamSpec2);
        KeyPair clientKeyPair = ClientkeyPair.generateKeyPair();

        PublicKey publicKey = clientKeyPair.getPublic();
        PrivateKey privateKey = clientKeyPair.getPrivate();

        X509Certificate x509cert = null;
        byte[] derCert = null;
        // generate the certificate
        try {
            x509cert = generateV3Certificate(clientKeyPair);
            derCert = x509cert.getEncoded();

        //Certificate test using verify:
        x509cert.checkValidity(new Date());
        x509cert.verify(x509cert.getPublicKey(), "SC");  //This cert is self-signed...
        System.out.println("valid certificate generated");

        //Another test: (verify not using cert.verify but rather calculating the signature)
        Signature verifier = Signature.getInstance("SHA384WITHECDSA", "SC");
        boolean result=false;
        verifier.initVerify(x509cert.getPublicKey()); // This cert is self-signed
        verifier.update(x509cert.getTBSCertificate());  //TBS is to get the "To Be Signed" part of the certificate - .getEncoded() gets the whole cert, which includes the signature
        result = verifier.verify(x509cert.getSignature());
        if (result == false)
        {
            System.out.println("signature validation failed");
        }
        //end of another verification
    }
    catch (Exception e)
    {
        //
    }
    return derCert;
} //GenerateMyClientCertificate

以同样的方式,我可以检查CA证书,这也是一个自签名证书:

//Certificate validity test using verify: -- This seems to work well for self-signed certificates...
        RootCaX509Cert.checkValidity(new Date());
        RootCaX509Cert.verify(RootCaX509Cert.getPublicKey(), "SC");  //This cert is self-signed...
        System.out.println("valid certificate generated");

        //Another test: (verify not using cert.verify but rather calculating the signature)
        Signature verifier = Signature.getInstance("SHA384WITHECDSA", "SC");
        boolean result=false;
        verifier.initVerify(RootCaX509Cert.getPublicKey()); // This cert is self-signed
        verifier.update(RootCaX509Cert.getTBSCertificate());  //TBS is to get the "To Be Signed" part of the certificate - .getEncoded() gets the whole cert, which includes the signature
        result = verifier.verify(RootCaX509Cert.getSignature());
        if (result == false)
        {
            System.out.println("signature validation failed");
        }

现在,我想使用CA证书的公钥检查用户证书。但是上述验证方法都不起作用:

        //Certificate validity test using verify: -- This seems to work well for self-signed certificates...
        ServerX509Cert.checkValidity(new Date());
        ServerX509Cert.verify(RootCaX509Cert.getPublicKey(), "SC");  //This cert was signed by CA
        System.out.println("valid certificate generated");

        //Another test: (verify not using cert.verify but rather calculating the signature)
        Signature verifier = Signature.getInstance("SHA384WITHECDSA", "SC");
        boolean result=false;
        verifier.initVerify(RootCaX509Cert.getPublicKey()); // This cert is signed by CA
        verifier.update(ServerX509Cert.getTBSCertificate());  //TBS is to get the "To Be Signed" part of the certificate - .getEncoded() gets the whole cert, which includes the signature
        result = verifier.verify(ServerX509Cert.getSignature());
        if (result == false)
        {
            System.out.println("signature validation failed");
        }

所以目前我只能检查自签名证书:( 我原以为使用RootCaX509Cert.getPublicKey()作为关键在这里会起作用,但事实并非如此。也许我误解了应该如何进行CA签名验证?

0 个答案:

没有答案