我有一个根 CA 证书和一个由 CA 签名的用户证书。在使用 Certutil 或 OpenSSL 的 Windows 下,我可以验证 CA 在用户证书签名上的签名是否正常。现在我正在尝试在 Android 下验证相同的签名。
我使用海绵城堡,但我不确定这一步是否完全必要。我使用 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 签名验证应该如何完成?