我正在尝试制作一个在 Delphi XE 中使用某些 Web 服务的程序。要连接到 Web 服务,我必须使用存储在 Windows 证书存储中的自签名证书。我使用 CertOpenSystemStore 打开证书存储,获取证书CertFindCertificateInStore
并使用SSL_CTX_use_certificate
. 这没问题。然后我得到公钥 blobCryptExportKey
并组成这样的私钥:
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
然后我设置它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 bignums,它们是正确的,其他一切看起来都很好。是的,调用函数时会发生错误ssl_read
。