如何使用 KeyFile 的客户端身份验证设置连接到 Web 服务的密码?
How to set password connecting to a web service with client-authentication for KeyFile?
我必须编写一个程序(Delphi XE5,Indy 10:TIdHTTP 和 TIdSSLIOHandlerSocketOpenSSL),它可以通过客户端身份验证连接到 Web 服务。经过几天的努力,终于成功了。我可以使用身份验证进行连接,设置 TIdSSLIOHandlerSocketOpenSSL 的 SSLOptions.CertFile 和 SSLOptions.KeyFile 属性。没关系。 (我从我的伙伴那里得到了一个 pfx 文件,我用 OpenSSL 将它导出到一个证书和一个私钥文件,所以我在程序中使用了这两个文件。)
我在表单上有一个 TButton、TMemo 和 TIdHTTP 组件。
源代码(Button 的点击事件 - IdHTTP1.Request.ContentType := '......' 行是必需的,只是为了服务器设置的通信):
procedure TForm1.Button1Click(Sender: TObject);
var
URL: string;
XML: TStrings;
S: string;
Req: TStream;
SL: TStringList;
SSL1 : TIdSSLIOHandlerSocketOpenSSL;
begin
XML := TStringList.Create;
XML.Add('<soap:Envelope xmlns:ns="http://docs.oasis-open.org/ws-sx/ws-trust/200512" ' +
'xmlns:soap="http://www.w3.org/2003/05/soap-envelope">');
…
XML.Add(' <soap:Body>');
…
XML.Add(' </soap:Body>');
XML.Add('</soap:Envelope>');
URL := 'https://…………………….';
end
Req := TStringStream.Create(XML.Text, TEncoding.UTF8);
try
SSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
SSL1.SSLOptions.CertFile := 'd:\certificate.pem';
SSL1.SSLOptions.KeyFile := 'd:\private.pem';
SSL1.SSLOptions.Mode := sslmClient;
try
SSL1.SSLOptions.Method := sslvSSLv23;
IdHTTP1.IOHandler := SSL1;
IdHTTP1.Request.ContentType := 'application/soap+xml;charset=UTF-8;action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue"';
S := IdHTTP1.Post(URL, Req);
finally
SSl1.Free;
end;
finally
Req.Free;
end;
ResultMemo.Lines.Add(Format('Response Code: %d', [IdHTTP1.ResponseCode]));
ResultMemo.Lines.Add(Format('Response Text: %s', [IdHTTP1.ResponseText]));
SL := TStringList.Create;
try
SL.Text := S;
ResultMemo.Lines.AddStrings(SL);
finally
SL.Free;
end;
end;
问题是:我的伙伴说如果我使用的文件没有密码保护,这种情况不是最好的。他们告诉我如何使用 OpenSSL 为 KeyFile 创建一个受密码保护(和加密)的文件。当我将此受密码保护的文件设置为 SSLOptions.KeyFile 时,我收到以下错误消息:“无法加载密钥,请检查密码。 error:0906A068:PEM routines:PEM_do_header:bad 密码已读取。”
我试过在idHTTP1.Request.Password属性设置密码,结果还是一样
问题:如果我必须使用受密码保护的密钥文件,我必须如何以及在哪里设置密钥文件的密码?因为我也要发布认证文件,所以最好的解决办法是在程序中设置密码,使用密码保护的KeyFile,而不是不使用密码保护的KeyFile。
非常感谢。
此致,
阿提拉
使用IdSSLIOHandlerSocketOpenSSL.OnGetPassword事件并在此处设置。
procedure TForm1.IdSSLIOHandlerSocketOpenSSL1GetPassword(var Password: string);
begin
Password := 'thepassword';
end;
我必须编写一个程序(Delphi XE5,Indy 10:TIdHTTP 和 TIdSSLIOHandlerSocketOpenSSL),它可以通过客户端身份验证连接到 Web 服务。经过几天的努力,终于成功了。我可以使用身份验证进行连接,设置 TIdSSLIOHandlerSocketOpenSSL 的 SSLOptions.CertFile 和 SSLOptions.KeyFile 属性。没关系。 (我从我的伙伴那里得到了一个 pfx 文件,我用 OpenSSL 将它导出到一个证书和一个私钥文件,所以我在程序中使用了这两个文件。)
我在表单上有一个 TButton、TMemo 和 TIdHTTP 组件。
源代码(Button 的点击事件 - IdHTTP1.Request.ContentType := '......' 行是必需的,只是为了服务器设置的通信):
procedure TForm1.Button1Click(Sender: TObject);
var
URL: string;
XML: TStrings;
S: string;
Req: TStream;
SL: TStringList;
SSL1 : TIdSSLIOHandlerSocketOpenSSL;
begin
XML := TStringList.Create;
XML.Add('<soap:Envelope xmlns:ns="http://docs.oasis-open.org/ws-sx/ws-trust/200512" ' +
'xmlns:soap="http://www.w3.org/2003/05/soap-envelope">');
…
XML.Add(' <soap:Body>');
…
XML.Add(' </soap:Body>');
XML.Add('</soap:Envelope>');
URL := 'https://…………………….';
end
Req := TStringStream.Create(XML.Text, TEncoding.UTF8);
try
SSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
SSL1.SSLOptions.CertFile := 'd:\certificate.pem';
SSL1.SSLOptions.KeyFile := 'd:\private.pem';
SSL1.SSLOptions.Mode := sslmClient;
try
SSL1.SSLOptions.Method := sslvSSLv23;
IdHTTP1.IOHandler := SSL1;
IdHTTP1.Request.ContentType := 'application/soap+xml;charset=UTF-8;action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue"';
S := IdHTTP1.Post(URL, Req);
finally
SSl1.Free;
end;
finally
Req.Free;
end;
ResultMemo.Lines.Add(Format('Response Code: %d', [IdHTTP1.ResponseCode]));
ResultMemo.Lines.Add(Format('Response Text: %s', [IdHTTP1.ResponseText]));
SL := TStringList.Create;
try
SL.Text := S;
ResultMemo.Lines.AddStrings(SL);
finally
SL.Free;
end;
end;
问题是:我的伙伴说如果我使用的文件没有密码保护,这种情况不是最好的。他们告诉我如何使用 OpenSSL 为 KeyFile 创建一个受密码保护(和加密)的文件。当我将此受密码保护的文件设置为 SSLOptions.KeyFile 时,我收到以下错误消息:“无法加载密钥,请检查密码。 error:0906A068:PEM routines:PEM_do_header:bad 密码已读取。”
我试过在idHTTP1.Request.Password属性设置密码,结果还是一样
问题:如果我必须使用受密码保护的密钥文件,我必须如何以及在哪里设置密钥文件的密码?因为我也要发布认证文件,所以最好的解决办法是在程序中设置密码,使用密码保护的KeyFile,而不是不使用密码保护的KeyFile。
非常感谢。
此致, 阿提拉
使用IdSSLIOHandlerSocketOpenSSL.OnGetPassword事件并在此处设置。
procedure TForm1.IdSSLIOHandlerSocketOpenSSL1GetPassword(var Password: string);
begin
Password := 'thepassword';
end;