我正在 delphi 10.3 中使用 indy 开发一个支持 SSL 的 MITM 代理。我使用 IdHttpServer 组件,它在 CommandOther 事件中工作。我设法让它动态解密和转储数据,然后重新加密并将其发送到浏览器,但我需要更改每个域的 idhttpserver 证书。我可以生成它们并安装我自己的 CA,但我找不到在我的代理工作时更改它们的方法。如果有人能告诉我如何做,我将不胜感激!
procedure TForm3.IdHTTPServer1CommandOther(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
S: string;
LClient: TIdtcpClient;
newsize:int64;
LBuf: TIdBytes;
Len: Integer;
var response:integer;
s3: TStringDynArray;
var cmd:string;
bytes:tidbytes;
oldstr,newstr:string;
ResponseCode, ResponseText: string;
Size: Int64;
ssl:tIdServerIOHandlerSSLopenssl;
begin
if not TextIsSame(ARequestInfo.Command, 'CONNECT') then Exit;
LClient := TIdtcpClient.Create(nil);
try
S := ARequestInfo.URI;
LClient.Host := Fetch(S, ':', True);
LClient.Port := StrToIntDef(S, 443);
LClient.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(LClient);
LClient.ConnectTimeout := 5000;
// connect and activate SSL between this proxy and the target server
LClient.Connect;
try
AResponseInfo.ResponseNo := 200;
AResponseInfo.ResponseText := 'Connection established';
AResponseInfo.WriteHeader;
// activate SSL between this proxy and the client
TIdSSLIOHandlerSocketOpenSSL(AContext.Connection.Socket).PassThrough:=false;
// pass data between AContext.Connection.IOHandler and LClient.IOHandler
//as needed.
// received data will be decrypted, and sent data will be encryted...
while AContext.Connection.Connected and lclient.Connected do
begin
//mitm traffic modification routine
end;
finally
LClient.Disconnect;
end;
finally
LClient.Free;
end;
end;
这是证书切换代码:
procedure TForm3.IdHTTPServer1Connect(AContext: TIdContext);
var
SSL: TIdSSLIOHandlerSocketOpenSSL;
begin
if AContext.Connection.Socket.Binding.Port = 443 then
begin
sslh:=tIdSSLIOHandlerSocketOpenSSL(AContext.Connection.IOHandler);
sslh.SSLOptions.CertFile:='Certificate.pem';
sslh.SSLOptions.keyfile:='PrivateKey.pem';
sslh.SSLOptions.RootCertFile:='certificateAuthorityCertificate.pem';
sslh.SSLOptions.SSLVersions:=[sslvSSLv23];
sslh.ssloptions.mode:=sslmBoth;
sslh.OnGetPassword:= IdServerIOHandlerSSLOpenSSL1GetPassword;
sslh.PassThrough:=false;
TIdSSLIOHandlerSocketOpenSSL(AContext.Connection).PassThrough:=false;
//memo2.Text:=AContext.Connection.IOHandler.ReadLn();
end;
end;
在表单上,我有一个 tidhttpserver 和 TIdServerIOHandlerSSLOpenSSL 作为它的 iohandler。
最佳答案
分配 OnQuerySSLPort
事件处理程序,无论请求什么 APort
,都会无条件地将 VUseSSL
参数设置为 False
。然后,在 OnConnect 事件中,如果 AContext.Connection.Socket.Binding.Port 属性为 443(或您想要在其上使用 HTTPS 的任何端口),您可以进行类型转换将 AContext.Connection.IOHandler
属性设置为 TIdSSLIOHandlerSocketBase
(或后代,如 TIdSSLIOHandlerSocketOpenSSL
如果使用 OpenSSL),根据需要配置其证书,然后设置将其 PassThrough
属性设置为 False
以完成 SSL/TLS 握手。
关于delphi - 在 IdHTTPServer 中动态更改 SSL 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57642388/