我的代码可以验证自签名证书,但在使用VeriSign颁发的证书时失败

时间:2014-10-28 11:37:23

标签: java security digital-signature

我的应用程序使用java安全API对文件进行签名并进行验证。 在签名时,我使用PFX文件和密码作为输入,签名后我使用字节生成签名文件。 验证过程中我使用签名文件,证书文件和签名文件作为输入。 请在下面的验证中找到我使用的代码:

 // 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);

请帮我解决,但尚未关闭。

1 个答案:

答案 0 :(得分:1)

如果您想自己这样做,是的,您必须遍历链中的证书,从信任锚到您想要的证书, 无论多长时间(它可能因不同的CA,类和不同时间而有所不同)。 使用“父”(下一个更高)证书中的公钥验证每个“子”(较低级别)证书上的签名只是一个 相当一部分;还需要许多其他步骤。 通常只是找到正确的证书可能是一个问题;如果您已经拥有正确的链条,那么您就有了先机。 但你确定你有“正确的”链条吗?对于给定的证书,通常有几种可能的链, 有时其中一些是有效的,但其他人已经过期或变得无法核实。 Verisign特别发布我相信所有最近的G5根目录下的证书,但提供了另一条路径 返回(有效)G1用于不是最新的重定向器,有时无法更新。

大多数情况的算法在“PKIX”RFC5280中定义, 除了用于撤销的OCSP RFC6960而不是CRL变得越来越普遍。 您可能会忽略跨层次结构和NameConstraints,而实际上并未使用AFAIK 像Verisign这样的公共CA,以及CA使用但是用户/服务员不关心的策略内容。 https://security.stackexchange.com/questions/37409/certificate-chain-checking有一个很好但不完整的介绍。

但你可能更好使用Java(真正的JCE) CertPathValidator for“PKIX” - 如果需要CertPathBuilder - 我已经提到过你了。这已经由专家编写和测试。只需调用即可 仍然有点复杂,但远不如重写它所做的所有事情那么复杂。