3

証明書を使用して文字列に署名する Java アプリケーションがあります。文字列をSHA1で暗号化して動作します。コードを Delphi 2010 に変換しようとしていますが、Java アプリと同じように (sha1 を使用して) 動作させる方法がわかりません。これまでのところ、私はこれを見つけました:

Delphi 7 アクセス Windows X509 証明書ストア

動作しますが、sha1 を使用せず、Java アプリを実行すると異なる結果が得られます。

Java コード

 char[] pass = (char[]) null;
 PrivateKey key = (PrivateKey) getKeyStore().getKey(alias, pass);
 Certificate[] chain = getKeyStore().getCertificateChain(alias);
 CertStore certsAndCRLs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(Arrays.asList(chain)), "BC");
 X509Certificate cert = (X509Certificate) chain[0];
 CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
 gen.addSigner(key, cert, CMSSignedDataGenerator.DIGEST_SHA1);
 gen.addCertificatesAndCRLs(certsAndCRLs);
 CMSProcessable data = new CMSProcessableByteArray(conteudoParaAssinar);
 CMSSignedData signed = gen.generate(data, true, "SunMSCAPI");
 byte[] envHex = signed.getEncoded();
 CertInfo certInfo = new CertInfo();
 certInfo.Hash = new BigInteger(envHex).toString(16);
 return certInfo;

Delphi コード

var
  lSigner: TSigner;
  lSignedData: TSignedData;
  fs: TFileStream;
  qt: integer;
  ch: PChar;
  msg : WideString;
  content : string;
  cert: TCertificate;
begin
  cert := Self.GetCert;
  content := 'test';
  lSigner := TSigner.Create(self);
  lSigner.Certificate := cert.DefaultInterface;
  lSignedData := TSignedData.Create(self);
  lSignedData.content := content;
  msg := lSignedData.Sign(lSigner.DefaultInterface, false, CAPICOM_ENCODE_BASE64);
  lSignedData.Free;
  lSigner.Free;

編集

Javaコードに基づいて、証明書情報をバイナリ形式で取得し、sha1を適用して16進数に変換する必要がありますか? これは正しい順序であり、Java コードと同じことですか? capicom tlb とハッシュ クラスにいくつかの SHA1 定数が表示されます。これらのクラスを使用する必要があるかもしれませんが、方法がわかりません。

4

2 に答える 2

3

Java Tomcat アプリと連携し、SHA-256 互換のハッシュを取得できるいくつかの Delphi アプリでDCPCryptを使用します。SHA1も簡単だと思います。

これが例です

function Sha256FileStreamHash(fs : TFileStream): String;
var
    Hash: TDCP_sha256;
    Digest: array[0..31] of byte;  // RipeMD-160 produces a 160bit digest (20bytes)
    i: integer;
    s: string;
begin
  if fs <> nil then
  begin
    fs.Seek(0, soFromBeginning);
    Hash:= TDCP_sha256.Create(nil);          // create the hash
    try
      Hash.Init;                                   // initialize it
      Hash.UpdateStream(fs,fs.Size);       // hash the stream contents
      Hash.Final(Digest);                          // produce the digest
      s:= '';
      for i:= 0 to 31 do
        s:= s + IntToHex(Digest[i],2);
      Result:= s;                              // display the digest
    finally
      Hash.Free;
    end;
  end;
end;
于 2011-06-22T00:51:47.213 に答える
0

まず、なぜ SHA-1 を使用していないと思いますか? CAPICOM の署名機能は SHA-1 署名でしか機能しないため、質問しています。

第二に、異なる結果が得られていることをどうやって知ることができますか? 答えを検証しようとしましたか? はいの場合、何を使用していますか?

3 番目に、CAPICOM について知っておく必要があることがあります。「コンテンツ」プロパティはワイドストリングです。これには、すべてのコンテンツが 16 ビットにパディングされるという事実を含め、さまざまな意味があります。入力データのサイズが異なる場合、異なる結果が得られます。

Javaコードに基づいて、証明書情報をバイナリ形式で取得し、sha1を適用して16進数に変換する必要がありますか?

いいえ。ICertificate オブジェクト (または、より可能性が高いのは ICertificate2) のインスタンスへのインターフェイスを取得し、それを直接使用するだけです。証明書の B64 エンコード バージョンがある場合は、新しい ICertificate インスタンスを作成してから、ICertificate.Import メソッドを呼び出すことができます。証明書自体のハッシュは、署名機関がその特定の証明書に署名するためにのみ使用されます。

ハッシュ アルゴリズムは、データ署名プロセス中に実際に使用されます。ライブラリはデータを読み取り、そのデータのハッシュを作成し (CAPICOM の場合は SHA-1 を使用)、そのハッシュ値にデジタル署名します。この削減が必要なのは、データ ブロック全体に署名するのは非常に遅く、ハードウェア暗号化システムを使用している場合はハッシュを保持するだけで済むためです。

これは正しい順序であり、Java コードと同じことですか?

はいといいえ。Java コードは、明示的な詳細で必要なすべてのステップを実行します。これは、CAPICOM では実行できない (そして実際には実行できない) ことです。ただし、互換性のある結果が得られるはずです。

また、署名自体に関係のない追加の手順もあります。ダミーの証明書情報データを作成し、署名された CMS メッセージの SHA-1 ハッシュ値を保存し、結果のインスタンスを返すように見えるため、何をするのかわかりません。これは、Java 開発者がハッシュ値を呼び出し元に戻す方法を見つけたものだと思います。

capicom tlb とハッシュ クラスにいくつかの SHA1 定数が表示されます。これらのクラスを使用する必要があるかもしれませんが、方法がわかりません。

HashedData クラスは、(サプライズ) データをハッシュするために使用されます。Signeddata と同じ制限があります。つまり、ワイドストリングでしか機能しないため、他のフレームワークとの互換性はせいぜい危険です。

最後の注意: Windows は、関数の CAPI グループを通じて、より包括的な暗号化関数へのアクセスを提供します。CAPICOM は、(ほとんど) スクリプト言語 (Web ページ上の JavaScript、VB など) で使用されるライブラリへのインターフェイスにすぎません。CAPICOM を使用すると適切に実行できないことに遭遇する可能性が高いため、CAPICOM の代わりに使用してみてください。その段階で、CAPI (または別のライブラリ) を使用して、すべてのアプリケーションの一部を書き直す必要があります。したがって、今すぐ時間を節約して、CAPICOM を使用する必要がない場合はスキップしてください。

于 2011-07-01T13:14:32.553 に答える