windows - 通过 OpenSSL 使用来自 Windows 证书库的证书和私钥

标签 windows delphi openssl certificate-store

我正在尝试制作一个在 Delphi XE 中使用某些 Web 服务的程序。要连接到 Web 服务,我必须使用存储在 Windows 证书库中的自签名证书。我使用 CertOpenSystemStore 打开证书存储,使用 CertFindCertificateInStore 获取证书并使用 SSL_CTX_use_certificate 进行设置。没问题。然后我用 CryptExportKey 得到公钥 blob 并像这样组成一个私钥:

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_PrivateKeySSL_CTX_check_private_key 进行设置 - 目前没问题。但是当数据传输开始时,我在 libeay32.dll 中遇到访问冲突。如果我从 .pem 文件加载 key ,一切都很好。我看不出我做错了什么,请帮忙:)

这是准确的错误信息:

Access violation at address 09881C5F in module 'libeay32.dll'. Read of address 00000000.

libeay32.dll 版本为 1.0.0.5。也尝试过 0.9 版的东西 - 得到同样的错误,只是地址不同。

下面是我在PrivKeyBlob2RSA中得到的RSA结构:

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 时。

最佳答案

在我看来,出现这些错误的最合理原因包括:

  1. OpenSSL dll (libeay32 ssleay.dll) 版本错误或声明 SSL 包装器时出错(在这种情况下,您可能需要升级 Indy 版本 10)。

  2. 根据 Ken 的评论,已经释放了您要传递给 DLL 的内存块。

  3. 您发布的代码中存在一些微妙的指针取消引用错误。对 CopyMemory 的调用可能缺少通过“PointerVariableName^”而不只是“PointerVariableName”的指针间接级别。如果您不清楚,请阅读“pascal 中的非类型化 var 参数和指针”。

关于windows - 通过 OpenSSL 使用来自 Windows 证书库的证书和私钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7913697/

相关文章:

delphi - 如何在客户端连接的 ListView 中存储标识符 - Indy 10

windows - 如何计算在windows批处理中编码的sha1 base64?

windows - 我应该使用哪个版本的 MSXML?

python - 在没有终端的情况下打开 kivy 小部件?

linux - Windows 的 Shell 脚本模拟器

delphi - 如何在 RadStudio XE3 选项中关联 .dpr 扩展名?

德尔福XE2 : Is it possible to create Mac GUI applications without FireMonkey?

java - POODLE 更新后,PayPal IPN 停止使用 Tomcat/Open SSL

heroku - x509 : certificate signed by unknown authority

windows - 在 windows 10 上安装 flume agent