求助delphi实现ssl验证客户端证书
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求助delphi实现ssl验证客户端证书相关的知识,希望对你有一定的参考价值。
参考技术A This document explains how to use certificate authentication when connecting to a site that requires certificate authentication. We are using Indy components on the client side and some server (MS IIS, Apache, …) on the server side. In the example we will be using http protocol, cause it is very easy to set such an environment.First of all we must get certificates and private keys for the client. Let''''s suppose that we got some private key/certificate pair from some Certificate Authority (like Verisign) and we have this listed in MS IE in Personal Certificates Store.
Task 1. Convert the certificate from MS format to PEM format used by OpenSSL
First we have to export the certificate, I don''''t write down but it is assumed that also private key is exported, to the PFX file (personal exchange format). We can protect this file with some password, but for let''''s not for the sake of example.
When we have this file, in our case is test_b.pfx, we have to convert it to PEM format. With IndySSL dll''''s we distribute also the precompiled openssl.exe utility that can be used to do the conversion.
The proper parameters are:
openssl.exe pkcs12 –in test_b.pfx –out test_b.pem
we will be asked to provide the password, first to unlock the pfx file (we didn''''t specify it) and then password for locking the private key part in pem file. We can specify this password that will be latter used to unlock the private key in the demo. Le''''t suppose that we use ?aaaa? for the password (four letters a).
If we look at the PEM file we will notice that we have two parts in it. The private key file and the certificate (public key) part and some informational statements. We should divide those two parts in separate file, cause we need them separated in Indy SSL clients.
So, let''''s create a first file called test_b_key.pem and copy/paste every thing between
-----BEGIN RSA PRIVATE KEY----- and
-----END RSA PRIVATE KEY-----
and those two lines included in this new file and save it.
Create also the certificate file called test_b_crt.pem and copy/paste every thing between
-----BEGIN CERTIFICATE----- and
-----END CERTIFICATE-----
and those two lines included in this new file and save it.
Now we need also the Certificate Authority certificate file. This can be obtained from the MSIE in Trusted Root Certificate Authority. Select the Authority that issued your certificate and export it in Base64 (cer) format. This format is also the same like PEM format so you can easily rename the file test_b_ca.crt to test_b_ca.pem and you have the proper file.
We have now all the files that we require so we can start coding in Delphi.
Let''''s create a new application.
Put IdHTTP component and IdSSLIOHandlerSocket on it and save the project.
Now we will specify those certificate files in the IdSSLIOHandlerSocket component.
Set the property:
- CertFile to test_b_crt.pem,
- KeyFile to test_b_key.pem,
- RootCertFile to test_b_ca.pem.
Set the property Method to sslvSSLv23 so the ssl protocol will negotiate the proper mode (SSL ver2 or SSL ver3) automatically.
Set the property VerifyDepth to 2, this means that we accept the server certificate (that we connect to), up to 2 levels of Certificate Chain (CA1 -> CA2 -> Server certificate). In our case we have only one level so value 2 will be fine.
Now we have to connect the components IdHTTP to IdSSLIOHandlerSocket. This is done by choosing the IdSSLIOHandlerSocket1 in IOHandler property of IdHTTP1 component.
Set the Port of IdHTTP1 to 443, that is the HTTPS protocol port.
Create a OnGetPassword event, that will be fired when the client will need to access the private key. In this event handler you specify the password for unlocking the key.
procedure TForm1.IdSSLIOHandlerSocket1GetPassword(var Password: String);
begin
Password := ''''aaaa'''';
end;
Now, add a button on a form that will trigger the read of http address, and a memo box that will show the results. We used something like this:
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Clear;
Memo1.Lines.Text := IdHTTP1.Get(''''https://rotel/test/'''');
end;
Now you can set the verify options like sslvrfPeer, will force checking if the other side has a proper valid certificate, sslvrfFailNoPeerCert, will check if the other side has the certificate (used in server applications mostly), sslvrfClientOnce, will check the certificate only once in the ssl session - not all requests will be checked.
If you specify the OnVerifyPeer event, you can additionally check the properties of other side certificate, for example a valid user certificate properties that match your user database, role of user or something like this.
Note that you have to set the property VerifyMode to verify Peer if you want to event OnVerifyPeer get triggered.
Sample of verification code:
function TForm1.IdSSLIOHandlerSocket1VerifyPeer(Certificate: TIdX509): Boolean;
begin
if Pos(''''INTELICOM'''', UpperCase(Certificate.Subject.OneLine)) > 0 then
Result := True
Else
Result := False;
end;
If you return the True value then the client will be authorized, elsewhere it will not. Either way the other side certificate must be valid. The purpose of this event is to narrow the group of users with valid certificates.
SSL 证书 (CA) 如何准确验证?
【中文标题】SSL 证书 (CA) 如何准确验证?【英文标题】:How SSL Certificates (CA) are validated exactly? 【发布时间】:2021-12-18 18:59:01 【问题描述】:我正在搜索有关如何执行 SSL 验证过程的算法,但几乎在所有地方,他们都将证书验证步骤解释为“证书由客户端检查”或类似的东西,但我想知道这背后的场景是什么。
我知道的是:
当客户端收到你想尝试握手的属于哪个网站/服务器的证书副本时,有一些指标显示webserver的public信息(我认为这是为了匹配您的浏览器已安装的缓存证书条目中的条目。)
一旦客户端将缓存证书与网络服务器的证书匹配,它就会开始验证它。 它使用缓存证书的公钥来解密网络服务器的签名。(?[不确定,因为公钥用于“加密”数据,而不是解密。这一步也可能完全错误。] )
一旦解密,它会比较缓存的签名和网络服务器的签名。如果相同,则证书有效。
我也听说过链子。我真的很想知道如何知道一个链,以及如何确定网络服务器的证书是否只是属于一个链。(?)
客户端如何检查 SSL 证书?我需要一步一步地得到答案并澄清。谢谢:)
编辑:
我认为这里的公钥用于“解密”而不是“加密”。所以公钥不负责每次加密,它也可以解密并且不加密一些数据。这里的神奇之处在于,由于公钥在这里解密,如果你想伪造证书,你应该拥有那个 CA 的私钥来应用加密的更改(因为只有 private 密钥可以加密数据) .但是现在,另一个问题来了...如果我们使用网络服务器的公钥解密它,然后更改签名中的条目,然后使用我们的自己的私钥再次加密它(我们生成它手动,它不属于服务器。),这实际上让我们表现得像一个 CA;最后覆盖证书以保存我们的自己的公钥,它能够解密用我们的自己的私钥加密的数据?
【问题讨论】:
【参考方案1】:加密和签名之间存在差异。
客户端使用公钥加密只有服务器才能使用服务器的私钥解密的数据。
Public Key 被客户端用来验证服务器发送的数据的签名,该数据只能由服务器的 Private Key 签名。
当客户端想要访问服务器时,服务器会向您发送包含公钥的证书。客户端通常网络浏览器会检查他的集成 CA 的列表证书,如果它包含它。
如果它包含它,客户端继续并获取授权此证书的 CA(证书颁发机构)。 如果没有找到但签名验证通过,客户端会收到警告说证书可能是自签名的并且可能是恶意的。 如果客户端无法验证签名,则说明证书无效。对于信任链,您可以查看***: https://en.wikipedia.org/wiki/Chain_of_trust
您需要在此信任链中才能在 CA 的网络浏览器集成“数据库”中注册。
希望它能回答你的问题,最好的问候,
M
【讨论】:
【参考方案2】:简单地说:
私钥 -> 解密和签名 公钥 -> 加密和验证
认证机构
是签署和保证认证真实性的权威机构。如果您信任 CA,那么您也信任它的证书。 朋友也是如此:如果你有一个你信任的朋友,这告诉你“我有一个我信任的朋友”,那么你也信任你朋友的朋友。
证书颁发机构链。
可以有多个中间CA,例如可以有
根证书颁发机构由根证书颁发机构签署的 WebServer 中间证书颁发机构
由 WebServer 的中间证书颁发机构签署的 Web 服务器证书用于签名代码的中间证书颁发机构,由根证书颁发机构签名
等为什么?
因为万一中间授权机构之一遭到破坏,您只能撤销其子证书。
在企业级别,每个 CA 都有不同的安全级别,例如,根证书颁发机构可以存储在保险箱内,并且仅在有两个或更多管理员时使用。
对于中间人,也许只有一个管理员可以管理它。
参考How SSL WorksHow HTTPS WorksWht digital certificates
【讨论】:
以上是关于求助delphi实现ssl验证客户端证书的主要内容,如果未能解决你的问题,请参考以下文章