Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我的代码可以验证自签名证书,但在使用VeriSign颁发的证书时失败_Java_Security_Digital Signature - Fatal编程技术网

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

Java 我的代码可以验证自签名证书,但在使用VeriSign颁发的证书时失败,java,security,digital-signature,Java,Security,Digital Signature,我的应用程序使用java安全API对文件进行签名和验证。 签名时,我使用PFX文件和密码作为输入,签名后,我使用字节生成签名文件。 在验证过程中,我使用签名文件、证书文件和签名文件作为输入。 请在下面找到我在验证中使用的代码: // KeyFilePath= path of certificate file // fileToVerify = path of signed file // signatureFilePath = path of signature file Inpu

我的应用程序使用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);

请帮助我解决此问题,因为它尚未关闭。

如果您想自己解决此问题,是的,您必须迭代从信任锚点到所需证书的链中的证书, 不管它有多长(它可能因不同的CA、类别和时间而异)。 使用“父级”(下一级)证书的公钥验证每个“子级”(较低级别)证书上的签名只是一个简单的过程 其中相当小的一部分;还需要采取许多其他步骤。 通常,仅仅找到正确的证书是一个问题;如果你已经有了一个正确的链条,你就有了一个领先的开始。 但是你确定你有正确的链条吗?对于给定的证书,通常存在多个可能的链, 有时其中一些是有效的,但另一些已经过期或无法验证。 特别是Verisign,我相信所有最近的证书都是在G5根目录下发布的,但提供了另一条路径 对于不是最新的,有时无法更新的版本,请返回(有效地)G1

大多数情况下的算法在“PKIX”中定义, 除了OCSP代替CRL进行撤销变得越来越普遍之外。 您可以忽略AFAIK实际上没有使用的跨层次结构和名称约束 通过像Verisign这样的公共CA,以及CAs使用但用户/中继用户不关心的策略。 有一个很好但不完整的介绍

但是您最好使用Java的(真正的JCE)CertPathValidator进行“PKIX”——如果需要CertPathBuilder-- 我已经告诉过你了。这已经由专家编写和测试。就这么说吧
仍然有点复杂,但远没有重写它所做的所有事情那么复杂。

byte[]sigtovify=newbyte[sigFileInputStream.available()
被记录为不正确使用了
InputStream.available()
,因此将其与零进行比较作为流结束测试。自签名证书由其“自己的”密钥签名,或者更准确地说,由证书中的公钥对的私钥签名。因此
x509certificate.verify(pubkey)
成功,但基本上是无用的,因为任何攻击者都可以自行签署欺诈证书。CA签署的证书由CA(私钥)签名,因此子证书可以而且通常必须通过定位父(CA)证书并使用该公钥进行验证,迭代,直到您到达自签名的根CA,并且仅因为它是手动受信任的(通常在信任库文件中),才可以信任它。。。。。。除了有效的签名外,证书链还需要很多其他东西才能有效(不是伪造或泄露),需要进行检查。这通常被称为PKI验证,或者更具体地说是PKIX验证,因为这种格式(为Internet分析的X.509证书等)是最常见的。对于Java来说,这是一个相当好的起点。感谢@dave_thompson_085的回复。在我的例子中,我需要通过verisign验证java中三个证书链的证书。那么这是否意味着我必须迭代三次才能获得根证书呢。从您的评论中,我了解到我们需要从CA证书中提取公钥。请告诉我验证签名所需的所有输入,即证书类型、签名文件等。非常感谢@dave_thompson_085的详细解释。我尝试了您提到的步骤,并能够使用颁发者证书验证服务器证书。但我还需要使用签名过程中生成的“签名”文件验证证书。为此,我得到了一个解决我的问题的示例,但它指出“CA证书的验证是可能的,因为样本证书是自签名的。在现实生活中,您会将此证书链检查到一个受信任的CA,以确保具有有效的证书。“因此,请您帮助我使用java代码,了解如何解决“将此证书链检查到一个受信任的CA,以确保具有有效的证书”的问题,提前谢谢