验证数字签名时如何绕过证书已过期验证

时间:2012-10-16 08:34:26

标签: java .net digital-signature pkcs#7

使用过期的公共证书验证Java中的数字签名(PKCS#7)时出现问题。 有关更多详细信息,可以在.NET中签名数据然后在Java中验证,但在使用Java签名数据时会出现证书过期错误,并且在Java中验证< / strong>即可。在这两种情况下,我都使用相同的验证方法,相同的私钥和公共证书。

请告诉我原因?如果我想在验证数字签名时绕过证书过期验证,该怎么办?

谢谢,

C#.NET中的签名方法

private static string SignData(byte[] data, string pkcs12FileUrl, string pkcs12Password)
    {
        X509Certificate2 signerCert = new X509Certificate2(pkcs12FileUrl, pkcs12Password);
        ContentInfo content = new ContentInfo(data);
        SignedCms signed = new SignedCms(content, true);
        CmsSigner signer = new CmsSigner(signerCert);
        signer.IncludeOption = X509IncludeOption.None;
        signed.ComputeSignature(signer);

        return Convert.ToBase64String(signed.Encode());
    }

Java中的Sign方法

public static String SignData(byte[] data, String pkcs12File, String pkcs12Password)
    throws Exception
{
        if(Security.getProvider("BC")==null)
        {
            Security.addProvider(new BouncyCastleProvider());
        }
        KeyStore keyStore = getPkcs12Info(pkcs12File, pkcs12Password);

        Enumeration<String> aliasesList = keyStore.aliases();
        String aliasName = "";
        while (aliasesList.hasMoreElements())
        {
            aliasName = aliasesList.nextElement().toString();
        }

        X509Certificate signerCert = (X509Certificate) keyStore.getCertificate(aliasName);
        PrivateKey privateKey = (PrivateKey) keyStore.getKey(aliasName,pkcs12Password.toCharArray());

        CMSSignedDataGenerator Signer = new CMSSignedDataGenerator();
        Signer.addSigner(privateKey, signerCert, CMSSignedDataGenerator.DIGEST_SHA1);

        CMSProcessableByteArray digestContent = new CMSProcessableByteArray(data);

        CMSSignedData Signed = Signer.generate(digestContent, false, "BC");
        return Base64.encode(Signed.getEncoded());

}

private static  KeyStore getPkcs12Info(String pkcs12File, String pkcs12Password) throws Exception
{
    //KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(pkcs12File), pkcs12Password.toCharArray());
        return keyStore;
}

验证Java中的方法

public static boolean VerifySignature(byte[] data, String digitalSignature, InputStream publicCertFile) throws Exception
{
    if(Security.getProvider("BC")==null)
    {
        Security.addProvider(new BouncyCastleProvider());
    }
    CertificateFactory factory = CertificateFactory.getInstance("X509","BC");
    X509Certificate publicCert = (X509Certificate)factory.generateCertificate(publicCertFile);
    CMSProcessableByteArray digestContent = new CMSProcessableByteArray(data);
    CMSSignedData Signed = new CMSSignedData(digestContent,Base64.decode(digitalSignature));
    SignerInformation Signer=(SignerInformation)Signed.getSignerInfos().getSigners().iterator().next();
    return Signer.verify(publicCert, "BC");
}

2 个答案:

答案 0 :(得分:1)

如果您签署的证书已经过期,那么它已经毫无意义。证书已过期,不应用于新用途。验证签名证书已过期的文档是有意义的,因为至少您知道证书在签署文档时有效。除非它显然是由.NET签署的。听起来像.NET中的一个bug给我。

答案 1 :(得分:1)

我发现了这个主题Java implementation of C# SignedCms并尝试用Java更改我的Sign方法的代码。最后,它运作良好。这是我在Java中更新的代码

public static String SignData(byte[] data, String pkcs12File, String pkcs12Password)
    throws Exception
{
        ByteArrayOutputStream byteArrOut = new ByteArrayOutputStream();
        DEROutputStream derOut = new DEROutputStream(byteArrOut);
        try
        {
            if(Security.getProvider("BC")==null)
            {
                Security.addProvider(new BouncyCastleProvider());
            }
            KeyStore keyStore = getPkcs12Info(pkcs12File, pkcs12Password);

            Enumeration<String> aliasesList = keyStore.aliases();
            String aliasName = "";
            while (aliasesList.hasMoreElements())
            {
                aliasName = aliasesList.nextElement().toString();
            }

            X509Certificate signerCert = (X509Certificate) keyStore.getCertificate(aliasName);
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(aliasName, pkcs12Password.toCharArray());

            List certList = new ArrayList();
            Store certs = new JcaCertStore(certList);

            JcaSimpleSignerInfoGeneratorBuilder builder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setDirectSignature(true);


            CMSSignedDataGenerator signer = new CMSSignedDataGenerator();
            signer.addSignerInfoGenerator(builder.build("SHA1withRSA", privateKey, signerCert));
            signer.addCertificates(certs);

            CMSTypedData msg = new CMSProcessableByteArray(data);
            CMSSignedData signed = signer.generate(msg, false);

            derOut.writeObject(signed.toASN1Structure().toASN1Primitive());
            return Base64.encode(byteArrOut.toByteArray());
        }
        catch(Exception ex)
        {
            throw ex;
        }
        finally
        {
            derOut.close();
            byteArrOut.close();
        }

}