我最近一直在处理FTP,而且我不确定Indy组件TIdFTP
的安全性。这就是为什么我创建了一些我希望与您分享的测试,以便您可以对最佳实践及其完成方式发表意见。
首先,我使用Object Inspector在组件中添加了用户名和密码:
创建了一个效果很好的简单连接:
procedure TForm1.FormActivate(Sender: TObject);
begin
try
FTP.Connect();
ShowMessage ('Connection success');
except
ShowMessage ('Connection failure');
end;
end;
此方法的问题在于,如果您使用像Resource Hacker这样的简单工具,您可以立即看到所有数据:
Host = 'ivstefano.com'
Password = 'testpass'
Username = 'testuser'
然后我决定通过将其从OI中删除并将其插入到代码中来做得更聪明一点:
FTP.Host:= 'ivstefano.com';
FTP.Username:= 'testuser';
FTP.Password:= 'testpass';
如果有人更聪明,他可以轻松使用像Hex编辑器这样的工具,看看exe中编译的是什么:
所以我最后做的是使用OTP(One Time Pad Wiki)创建加密工具,您可以从这里下载Sample OTP tool:
我用它用关键字'lemon'加密我的密码'testpass'。然后我用ASCII码加密的字符串(#25+#2+#3+#7+#117+#19+#31+#6
)和密钥(#108+#101+#109+#111+#110
),两者都是ASCII字符和在我的主ftp连接程序中使用它们再次使用OTP解密它们:
function opt(text, key: String): String;
var i: Integer;
begin
SetLength(Result, length(text));
for i:= 1 to length(text) do
Result[i]:= Char(Byte(text[i]) xor (i + Byte(key[i mod length(key)])));
end;
procedure TFTPTester.FormActivate(Sender: TObject);
var decyptedPass: String;
begin
decyptedPass:= opt(#25+#2+#3+#7+#117+#19+#31+#6, #108+#101+#109+#111+#110);
FTP.Host:= 'ivstefano.com';
FTP.Username:= 'testuser';
FTP.Password:= decyptedPass;
try
FTP.Connect();
ShowMessage ('Connection success with pass: ' + decyptedPass);
except
ShowMessage ('Connection failure');
end;
end;
正如你可以看到它正确连接:
如果我们再次查看Hex,我们可以看到密钥短语和加密密码在这里,但至少不是明文密码:
结论:“黑客”仍然可以看到密钥短语和加密密码,但是如果使用密钥解密密码是更难的,因为他必须对代码进行反向工程并查看何种加密我用过。基本上我可以创建自己的加密和解密,所以它不是必需的OTP,但如果有人更先进,他仍然可以看到我解密加密密码并通过使用密钥将其应用于加密传递来访问我的FTP。
其他想法:也许混淆Delphi代码会是一个更好的选择?
问题:有什么更好的方法可以保护您的密码?
来源:这里可以找到FTPTester和OTP生成器的源代码:Link to both
答案 0 :(得分:5)
存储密码的方式并不重要。您使用的任何类型的存储都将通过足够的逆向工程来破解。迟早,纯文本版本必须在传递给TIdFTP之前在内存中解密,并且有一些工具(IDA等)可以在解密发生后查看该内存。只需在调试器下运行可执行文件,并在Password
属性设置器或Connect
方法中放置一个断点,并在命中时查看内存。
更糟糕的是,FTP协议无论如何都以纯文本形式传输密码,因此即使只是普通的数据包嗅探器(如Wireshark)也能够在不破解可执行文件的情况下看到它,除非你使用SSL( Indy 9及更早版本不支持FTP - 升级到Indy 10。
答案 1 :(得分:2)
我会使用一些软件保护工具,例如asprotect来加密你的exe文件。
但无论如何,Remy Lebeau说FTP将密码作为纯文本发送,这是一个很大的安全漏洞......