27

Delphi XE で Web サービスを使用するプログラムを作成しようとしています。Web サービスに接続するには、Windows 証明書ストアに保存されている自己署名証明書を使用する必要があります。CertOpenSystemStore で証明書ストアを開き、証明書を取得してCertFindCertificateInStoreで設定しSSL_CTX_use_certificateます。これで問題ありません。次に、公開鍵のブロブを取得し、次のCryptExportKeyような秘密鍵を作成します。

function PrivKeyBlob2RSA(const AKeyBlob: PByte; const ALength: Integer; const ASSLCtx: PSSL_CTX): IdSSLOpenSSLHeaders.PEVP_PKEY;
var
  modulus: PByte;
  bh: PBLOBHEADER;
  rp: PRSAPUBKEY;
  rsa_modlen: DWORD;
  rsa_modulus: PAnsiChar;
  rkey: PRSA;
begin
  bh := PBLOBHEADER(AKeyBlob);
  Assert(bh^.bType = PUBLICKEYBLOB);
  rp := PRSAPUBKEY(AKeyBlob + 8);
  Assert(rp.magic = $31415352);
  rsa_modulus := PAnsiChar(Integer(Pointer(rp))+12);
  rkey := RSA_new_method(ASSLCtx.client_cert_engine);
  rkey^.References := 1;
  rkey^.e := BN_new;
  rkey^.n := BN_new;
  BN_set_word(rkey^.e, rp^.pubexp);
  rsa_modlen := (rp^.bitlen div 8) + 1;
  modulus := AllocMem(rsa_modlen);
  CopyMemory(modulus, rsa_modulus, rsa_modlen);
  RevBuffer(modulus, rsa_modlen);
  BN_bin2bn(modulus, rsa_modlen, rkey^.n);
  Result := EVP_PKEY_new;
  EVP_PKEY_assign_RSA(Result, PAnsiChar(rkey));
end;

SSL_CTX_use_PrivateKeyそれから andでセットアップしましたSSL_CTX_check_private_key- 今のところ問題ありません。しかし、データ転送が始まると、libeay32.dll でアクセス違反が発生します。.pem ファイルからキーをロードすると、すべて問題ありません。何が間違っているのかわかりません。助けてください:)

正確なエラーメッセージは次のとおりです。

モジュール「libeay32.dll」のアドレス 09881C5F でアクセス違反が発生しました。アドレス 00000000 の読み取り。

libeay32.dll のバージョンは 1.0.0.5 です。バージョン0.9.somethingでも試してみました-同じエラーが発生しましたが、アドレスが異なります。

以下は、私が取得する RSA 構造ですPrivKeyBlob2RSA

pad    0
version  0
meth       $898030C
engine     nil
n      $A62D508
e      $A62D4D8
d      nil
p      nil
q      nil
dmp1       nil
dmq1       nil
iqmp       nil
ex_data (nil, -1163005939 {$BAADF00D})
references  1
flags      6
_method_mod_n   nil
_method_mod_p   nil
_method_mod_q   nil
bignum_data nil {#0}
blinding    nil
mt_blinding nil

n と e の bignum をチェックしたところ、それらは正しく、他のすべては問題ないように見えました。はい、 function を呼び出すときにエラーが発生しますssl_read

4

1 に答える 1

1

これらのエラーが発生する最も合理的な理由は次のとおりです。

  1. OpenSSL dll (libeay32 ssleay.dll) のバージョンが間違っているか、SSL ラッパーの宣言にエラーがあります (この場合、Indy バージョン 10 へのアップグレードが必要になる場合があります)。

  2. Ken のコメントによると、DLL に渡すメモリ ブロックは既に解放されています。

  3. あなたが投稿したコードのいくつかの微妙なポインター逆参照のバグ。CopyMemory の呼び出しで、"PointerVariableName" だけでなく、"PointerVariableName^" によるポインター間接化のレベルが欠落している可能性があります。不明な場合は、「型指定されていない var パラメーターとパスカルのポインター」を読んでください。

于 2012-06-09T19:56:26.270 に答える