web-dev-qa-db-ja.com

JAVA)でPKCS#7を使用してデータに署名します

PKCS#7を使用してテキストファイル(将来的には.exeファイルなど)に署名し、Javaを使用して署名を確認したいと思います。

  1. 何を知る必要がありますか?
  2. API(.jarおよびドキュメント)はどこにありますか?
  3. データに署名してデータを検証するために従う必要のある手順は何ですか?

可能であれば、コードスニペットを提供してください。

12
user1269042

PKCS7デジタル署名を生成するには、次の2つの弾力がある城の瓶が必要だと思います。

  • bcprov-jdk15on-147.jar(JDK 1.5-JDK 1.7の場合)

  • bcmail-jdk15on-147.jar(JDK 1.5-JDK 1.7の場合)

弾力がある城の瓶は ここ からダウンロードできます。

公開鍵と秘密鍵のペアを使用してキーストアを設定する必要があります。デジタル署名を生成するための秘密鍵と、それを検証するための公開鍵のみが必要です。

Pkcs7がコンテンツに署名する方法は次のとおりです(簡潔にするために例外処理は省略されています):

import Java.io.FileInputStream;
import Java.io.InputStream;
import Java.security.KeyStore;
import Java.security.PrivateKey;
import Java.security.Security;
import Java.security.cert.Certificate;
import Java.security.cert.X509Certificate;
import Java.util.ArrayList;
import Java.util.List;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.encoders.Base64;

public final class PKCS7Signer {

    private static final String PATH_TO_KEYSTORE = "/path/to/keyStore";
    private static final String KEY_ALIAS_IN_KEYSTORE = "My_Private_Key";
    private static final String KEYSTORE_PASSWORD = "MyPassword";
    private static final String SIGNATUREALGO = "SHA1withRSA";

    public PKCS7Signer() {
    }

    KeyStore loadKeyStore() throws Exception {

        KeyStore keystore = KeyStore.getInstance("JKS");
        InputStream is = new FileInputStream(PATH_TO_KEYSTORE);
        keystore.load(is, KEYSTORE_PASSWORD.toCharArray());
        return keystore;
    }

    CMSSignedDataGenerator setUpProvider(final KeyStore keystore) throws Exception {

        Security.addProvider(new BouncyCastleProvider());

        Certificate[] certchain = (Certificate[]) keystore.getCertificateChain(KEY_ALIAS_IN_KEYSTORE);

        final List<Certificate> certlist = new ArrayList<Certificate>();

        for (int i = 0, length = certchain == null ? 0 : certchain.length; i < length; i++) {
            certlist.add(certchain[i]);
        }

        Store certstore = new JcaCertStore(certlist);

        Certificate cert = keystore.getCertificate(KEY_ALIAS_IN_KEYSTORE);

        ContentSigner signer = new JcaContentSignerBuilder(SIGNATUREALGO).setProvider("BC").
                build((PrivateKey) (keystore.getKey(KEY_ALIAS_IN_KEYSTORE, KEYSTORE_PASSWORD.toCharArray())));

        CMSSignedDataGenerator generator = new CMSSignedDataGenerator();

        generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").
                build()).build(signer, (X509Certificate) cert));

        generator.addCertificates(certstore);

        return generator;
    }

    byte[] signPkcs7(final byte[] content, final CMSSignedDataGenerator generator) throws Exception {

        CMSTypedData cmsdata = new CMSProcessableByteArray(content);
        CMSSignedData signeddata = generator.generate(cmsdata, true);
        return signeddata.getEncoded();
    }

    public static void main(String[] args) throws Exception {

        PKCS7Signer signer = new PKCS7Signer();
        KeyStore keyStore = signer.loadKeyStore();
        CMSSignedDataGenerator signatureGenerator = signer.setUpProvider(keyStore);
        String content = "some bytes to be signed";
        byte[] signedBytes = signer.signPkcs7(content.getBytes("UTF-8"), signatureGenerator);
        System.out.println("Signed Encoded Bytes: " + new String(Base64.encode(signedBytes)));
    }
}
14
Zaki

PKCS#7は現在CMS(Cryptographic Message Syntax)として知られており、作成するにはBouncy CastlePKIXライブラリが必要です。十分なドキュメントと確立されたメーリングリストがあります。

コードスニペットは提供しません。ハウスルールに違反しています。最初に自分で試してください。

4
Maarten Bodewes