-3

当我们使用以下类org.bouncycastle.cms.CMSSignedDataorg.bouncycastle.cms.CMSSignedDataGenerator对数据进行签名时,我应该向文件写入什么以验证签名

非常感谢

我已经编写了代码来实现这一点,但我遇到了异常

public class T2 {
    public static String ROOT_ALIAS = "root";
    public static String INTERMEDIATE_ALIAS = "intermediate";
    public static String END_ENTITY_ALIAS = "end";
    public static String PLAIN_TEXT = "Hello World!123";
    private static final char[] KEY_PASSWORD = "keyPassword".toCharArray();

    public static CMSSignedData signData(KeyStore keyStore,
            byte[] plainTextToSign) throws Exception {
        // GET THE PRIVATE KEY
        PrivateKey key = (PrivateKey) keyStore.getKey(END_ENTITY_ALIAS,
                KEY_PASSWORD);

        Certificate[] chain = keyStore.getCertificateChain(END_ENTITY_ALIAS);
        CertStore certsAndCRLs = CertStore.getInstance("Collection",
                new CollectionCertStoreParameters(Arrays.asList(chain)), "BC");
        X509Certificate cert = (X509Certificate) chain[0];

        // set up the generator
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        gen.addSigner(key, cert, CMSSignedDataGenerator.DIGEST_SHA224);
        gen.addCertificatesAndCRLs(certsAndCRLs);

        // create the signed-data object
        CMSProcessable data = new CMSProcessableByteArray(plainTextToSign);
        CMSSignedData signed = gen.generate(data, "BC");

        // recreate
        signed = new CMSSignedData(data, signed.getEncoded());
        // ContentInfo conInf = signed.getContentInfo();
        // CMSProcessable sigContent = signed.getSignedContent();

        new File("D:\\pkcs7\\encrypted-file.p7b");
        FileOutputStream fileOuputStream = new FileOutputStream(
                "D:\\pkcs7\\encrypted-file.p7b");
        fileOuputStream.write(signed.getEncoded());
        // fileOuputStream.flush();
        fileOuputStream.close();
        return signed;
    }

    public static boolean verifyData(KeyStore keyStore) throws Exception {

        File file = new File("D:\\pkcs7\\encrypted-file.p7b");
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] signedByte = new byte[(int) file.length()];
        fileInputStream.read(signedByte);
        fileInputStream.close();

        // verification step
        X509Certificate rootCert = (X509Certificate) keyStore
                .getCertificate(ROOT_ALIAS);

        CMSSignedData signed = new CMSSignedData(signedByte);
        if (isValidSignature(signed, rootCert)) {
            System.out.println("verification succeeded");
            return true;
        } else {
            System.out.println("verification failed");
        }
        return false;
    }

    /**
     * Take a CMS SignedData message and a trust anchor and determine if the
     * message is signed with a valid signature from a end entity entity
     * certificate recognized by the trust anchor rootCert.
     */
    @SuppressWarnings("rawtypes")
    private static boolean isValidSignature(CMSSignedData signedData,
            X509Certificate rootCert) throws Exception {

        boolean[] bArr = new boolean[2];
        bArr[0] = true;
        CertStore certsAndCRLs = signedData.getCertificatesAndCRLs(
                "Collection", "BC");
        SignerInformationStore signers = signedData.getSignerInfos();
        Iterator it = signers.getSigners().iterator();

        if (it.hasNext()) {
            SignerInformation signer = (SignerInformation) it.next();
            SignerId signerConstraints = signer.getSID();
            signerConstraints.setKeyUsage(bArr);
            PKIXCertPathBuilderResult result = buildPath(rootCert,
                    signer.getSID(), certsAndCRLs);
            return signer.verify(result.getPublicKey(), "BC");
        }

        return false;
    }

    /**
     * Build a path using the given root as the trust anchor, and the passed in
     * end constraints and certificate store.
     * <p>
     * Note: the path is built with revocation checking turned off.
     */
    public static PKIXCertPathBuilderResult buildPath(X509Certificate rootCert,
            X509CertSelector endConstraints, CertStore certsAndCRLs)
            throws Exception {
        CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC");
        PKIXBuilderParameters buildParams = new PKIXBuilderParameters(
                Collections.singleton(new TrustAnchor(rootCert, null)),
                endConstraints);

        buildParams.addCertStore(certsAndCRLs);
        buildParams.setRevocationEnabled(false);

        return (PKIXCertPathBuilderResult) builder.build(buildParams);
    }
}
4

1 回答 1

0

当签名包装时,您不需要向文件中写入任何内容 - 签名操作的产品是您使用签名包包装的数据。请注意,处理原始未签名数据的应用程序不能直接处理此类签名数据。例如。如果您使用包装 PKCS#7/CMS 签名对 PDF 文档进行签名,Adobe Reader 将无法直接打开签名数据(直到签名被删除)。通过将签名数据提供给验证程序来验证签名。

使用分离签名,签名操作的产物是签名块本身,您可以将其存储在单独的文件中或作为某些文件系统上的备用数据流或数据库中的单独字段中。在这种情况下,您的原始数据保持不变。通过将原始数据和签名块提供给验证程序来验证签名。

于 2012-06-22T09:49:38.567 回答