-3

次のクラスorg.bouncycastle.cms.CMSSignedDataおよびorg.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 に答える