0

文書に署名する方法があります。

public static void sign(String src, String dest,
            java.security.cert.Certificate[] chain, PrivateKey pk,
            String digestAlgorithm, String provider, CryptoStandard subfilter,
            String reason, String location) throws GeneralSecurityException,
            IOException, DocumentException, com.itextpdf.text.DocumentException {

        // Creating the reader and the stamper
        PdfReader reader = new PdfReader(src);
        FileOutputStream os = new FileOutputStream(dest);
        PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');

        // Creating the appearance
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setVisibleSignature(new Rectangle(0, 100, 50, 300), 1, "sig");

        // Creating the signature
        ExternalDigest digest = new BouncyCastleDigest();
        ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, provider);     
        MakeSignature.signDetached(appearance, digest, signature, chain, null,null, null, 0, subfilter);


    }

BouncyCastleProvider を使用すると、すべてがうまく機能します。

BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(new FileInputStream(KEYSTORE), PASSWORD);
        String alias = (String) ks.aliases().nextElement();
        PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);
        java.security.cert.Certificate[] chain = ks.getCertificateChain(alias);

        for (int i = 0; i < chain.length; i++) {
            System.out.println(("Public Key"+chain[i].getPublicKey()));
        }
        System.out.println("Priate Key:"+       Arrays.toString(pk.getEncoded()));
        System.out.println("Lengh of key is:"+       Arrays.toString(pk.getEncoded()).length());


        sign(SRC, String.format(DEST, 1), chain, pk,DigestAlgorithms.SHA256, provider.getName(),CryptoStandard.CMS, "Test 1", "Ghent" );

それはよく署名し、結果は次のとおりです。

Public Key Sun RSA public key, 2048 bits. I have only Self Sign sertificate here. Created By Key tool.
  modulus: 19757623340732442247234242 ... and etc
  public exponent: 65537
Priate Key:[48, -126, 4, -66, 2, 1, ... and etc ]
Lengh of key is:5618

Wen I use My provider. ランタイム エラーや例外はありませんが、pdf ファイルを開くと、署名エラーが発生します。adobe reader には「:少なくとも 1 つの署名が無効です:」というアラートがあります。証明書を表示しようとすると、「署名の検証中にエラーが発生しました。検証中にエラーが発生しました。内部暗号化ライブラリ エラー。エラー コード: 0x2726" "

A はルート CA です。B は A の子です。C は署名者証明書です。T証明書、AAの子供も持っています

  MyProvider provider= newMyProvider();


    CallbackHandler console= new com.sun.security.auth.callback.TextCallbackHandler();
    provider.setCallbackHandler(console);    

    Security.addProvider(provider);
    KeyStore ks = KeyStore.getInstance("KeyStore");
    ks.load(null, new char[] {});


    List < java.security.cert.Certificate  > chainList = new ArrayList< java.security.cert.Certificate>();

    System.out.println("My Certificates in chain:");
      Enumeration<String> aliases = ks.aliases();
        while (aliases.hasMoreElements()) {
            String alias = aliases.nextElement();

                  if( alias.equalsIgnoreCase("T")
                 continue;

            if (ks.isCertificateEntry(alias)) {
                X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
                if(!chainList.contains(ks.getCertificate(alias))){
                    chainList.add(ks.getCertificate(alias));
                }
                System.out.println("Public Key"+(cert.getPublicKey()));
            }
        }
        java.security.cert.Certificate[]  chain =  new   java.security.cert.Certificate[chainList.size()];
        chainList.toArray(chain);
enter code here




    PrivateKey pk = (PrivateKey) ks.getKey("C", null);
    System.out.println("Priate Key:"+       Arrays.toString(pk.getEncoded()));
    System.out.println("Lengh of key is:"+       Arrays.toString(pk.getEncoded()).length());     
    sign(SRC, String.format(DEST, 1), chain,  pk, DigestAlgorithms.SHA256, provider.getName(), CryptoStandard.CMS, "Test sign", "testing");

コマンドラインの結果は次のとおりです。

  My Certificates in chain.  First is Main CA .
Public Key Sun RSA public key, 4096 bits
  modulus: 7233349847339212226486269.... and etc
  public exponent: 65537

Public Key Sun RSA public key, 4096 bits
  modulus: 8191375554227623097382171... and etc
  public exponent: 65537

Public Key  Sun RSA public key, 4096 bits
  modulus: 8221477538578824228200634... and etc
  public exponent: 65537

Priate Key:[66, 69, 105, 106, 105, 192 ... and etc]
Lengh of key is:306

プロバイダーを使用すると、PDF ファイルを開くと署名エラーが発生します。

:少なくとも 1 つの署名が無効です:
証明書を表示しようとすると、「署名の検証中にエラーが発生しました。検証中にエラーが発生しました。内部暗号化ライブラリ エラーです。エラー コード: 0x2726」というアラートが表示されました。

4

1 に答える 1

0

(ASN.1 ダンプを使用して) 署名を調べると、次のことがわかります。

  1. 発行された証明 書を証明書 CertificateSetに含めます
    • C = GE、O = ジョージア司法省、OU = 市民登録局、CN = GEO ルート CA
    • C = GE、O = ジョージア司法省、OU = 市民登録局、CN = GEO 署名 CA
    • C = GE、O = ジョージア司法省、OU = 市民登録局、CN = GEO 認証 CA
  2. SignerInfosid SignerIdentifierで、「GEO Root CA」証明書に関連付けられた秘密鍵を使用して署名したと主張します

コードを見ると、問題 1 は、キー ストアの内容が考えているものと異なることを示しています。一方では、「GEO Authentication CA」が「T」と等しくないエイリアスで少なくとも 1 回存在し、他方では、署名者証明書が含まれていないようです (またはエイリアス「T」があり、無視されます)。そのため)。ただし、秘密鍵は「C」として含まれています。

問題 2 は、iText が証明書配列の最初のエントリが署名者証明書であると想定しているという事実によるものです。chainList,「GEO Root CA」はキーストアで最初に見つかった証明書のように見えるため、これはあなたの最初の証明書でchain,あり、iText によって署名者証明書であると見なされます。

問題を解決するには、

  1. キーストアを調べて、関連する秘密鍵だけでなく、署名者証明書も含まれていることを確認してください。
  2. chain署名者証明書が証明書配列の最初にあることを確認してください。

ところで、あなたはまだ使ってみましたか

Certificate[] chain = ks.getCertificateChain("C");

証明書チェーンを取得するには? これは通常、PDF ドキュメントのデジタル署名で使用されます...

于 2013-06-02T10:53:52.880 に答える