3

手元に問題があります。Java を知らない私の同僚は、次のように OpenSSL コマンドを使用してファイルに署名しています。

openssl smime -binary -sign -certfile WWDR.pem -signer passcertificate.pem \
  -inkey passkey.pem -in manifest.json -out signature -outform DER \
  -passin pass:12345

ご覧のとおり、署名を生成するために openssl コマンドに渡される 3 つのファイルがここにあります。

ここで、Java を使用して同じ機能を複製したいと考えています。これは、署名されると想定されるコンテンツが動的であり、本質的にサーバー側であるためです。私は、BouncyCastle が進むべき道であることを読みました。しかし、そのライブラリを使用する方法がわかりません。私も暗号化技術にはあまり詳しくありません。上記の 3 つのファイルすべてを使用してコンテンツに署名する方法がわかりませんmanifest.json

誰かが私を正しいコードに案内してくれるか、私に始めさせてくれれば、私はあなたの努力に非常に感謝します.

4

3 に答える 3

5

また、そのopensslコマンドをJavaで複製する必要がありましたが、これが私がそれを達成した方法です。ランタイムを使用する必要はありません。

public byte[] signMobileConfig(byte[] mobileconfig) 
            throws CertificateEncodingException, PEMException, FileNotFoundException, IOException, CertificateException, OperatorCreationException, CMSException {
    Security.addProvider(new BouncyCastleProvider());

    X509CertificateHolder caCertificate = loadCertfile();

    JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter();
    X509Certificate serverCertificate = certificateConverter.getCertificate(loadSigner());

    PrivateKeyInfo privateKeyInfo = loadInKey();
    PrivateKey inKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo);
    ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(inKey);

    CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
    JcaDigestCalculatorProviderBuilder digestProviderBuilder = new JcaDigestCalculatorProviderBuilder().setProvider("BC");
    JcaSignerInfoGeneratorBuilder generatotBuilder = new JcaSignerInfoGeneratorBuilder(digestProviderBuilder.build());

    generator.addSignerInfoGenerator(generatotBuilder.build(sha1Signer, serverCertificate));
    generator.addCertificate(new X509CertificateHolder(serverCertificate.getEncoded()));
    generator.addCertificate(new X509CertificateHolder(caCertificate.getEncoded()));

    CMSProcessableByteArray bytes = new CMSProcessableByteArray(mobileconfig);
    CMSSignedData signedData = generator.generate(bytes, true);

    return signedData.getEncoded();
}

そして、ファイルをロードする方法は次のとおりです。

public X509CertificateHolder loadSigner() throws FileNotFoundException, IOException {
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.crt");
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream));
    return (X509CertificateHolder) parser.readObject();
}

public PrivateKeyInfo loadInKey() throws FileNotFoundException, IOException {
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.key");
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream));
    return (PrivateKeyInfo) parser.readObject();
}

public X509CertificateHolder loadCertfile() throws FileNotFoundException, IOException {
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.crt");
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream));
    return (X509CertificateHolder) parser.readObject();
}

これは私のファイルマッピングです:

myCrtFile.crt -> signerCertHolder
myKeyFile.key -> privateKeyInfo
bundleCertificate.crt -> certificateHolder
于 2016-04-15T13:29:18.473 に答える
3

まず、BouncyCastle を理解するのに苦労することを気にしないでください。これは非常に便利な API ですが、ドキュメントが不十分です。最善の策は、API の使用方法を説明する例を検索することです。

私は以前に SMIME に BouncyCastle を使用したことがないので (主に PGP および/または JCE に使用したことがあります)、" bouncycastle smime example" を簡単に検索した結果、このページ、具体的にはこの例にたどり着きました。

うまくいけば、これが良いスタートであり、さらにグーグルが使用中の API クラスを理解するのに役立ちます。この例だけで 80% は達成できると思います。


入力ファイルの目的について混乱がある場合:

-certfile WWDR.pem-これは、メッセージで指定する追加の証明書です。署名されたメッセージの受信者は、署名を検証するときにこの証明書を考慮します。

-signer passcertificate.pem-これは、署名キーに直接対応する証明書です。

-inkey passkey.pem-これはあなたの署名鍵です

于 2012-10-05T07:32:17.273 に答える
-1

したがって、誰かが上記の問題をどのように解決したのか疑問に思っている場合は、次のようにします。

JavaのRuntimeオブジェクトを使用しました!

String openSSLCommand = openssl smime -binary 
-sign -certfile WWDR.pem -signer passcertificate.pem
-inkey passkey.pem -in manifest.json -out signature -outform DER
-passin pass:12345

Process process = Runtime.getRuntime().exec(openSSLCommand);

みんなありがとう

于 2012-10-12T22:07:44.733 に答える