I have been dealing with FTP lately and I'm not sure about the security of the Indy component TIdFTP
. That is why I have created some tests which I want to share with you so you could give your opinion of best practices and how it is done.
First of all I just added the username and password in the component using the Object Inspector:
And created a simple connection which works well:
procedure TForm1.FormActivate(Sender: TObject);
begin
try
FTP.Connect();
ShowMessage ('Connection success');
except
ShowMessage ('Connection failure');
end;
end;
The problem with this method is that if you use a simple tool like Resource Hacker you can immediately see all that data:
Host = 'ivstefano.com'
Password = 'testpass'
Username = 'testuser'
Then I decided to be a little bit smarter by removing it from the OI and inserting it in the code as everybody else does:
FTP.Host:= 'ivstefano.com';
FTP.Username:= 'testuser';
FTP.Password:= 'testpass';
Still if somebody is smarter he can use with ease some tool like Hex editor and see what is in compiled in the exe:
So what I finally did was to make an encryption tool using OTP(One Time Pad Wiki) which you can download from here Sample OTP tool:
I used it to encrypt my password 'testpass' with the keyword 'lemon'. Then I took the OTP encrypted string (#25+#2+#3+#7+#117+#19+#31+#6
) and the key(#108+#101+#109+#111+#110
), both in ASCII sum of characters and used them in my main ftp connection program to decrypt them using OTP again:
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;
And as you can see it connects properly:
And if we look at the Hex again we can see that the keyphrase and the encrypted password are here but at least not the plain text password:
Conclusion: Still, the "hacker" can see the keyphrase and the encrypted pass but it is going to be harder to guess how to decrypt the pass using the key because he has to reverse engineer the code and see what kind of encryption I have used. Basically I can invent my own encryption and decryption so it is not necessary OTP but if somebody is more advanced he still could see the way I decrypt the encrypted password and access my FTP by applying it to the encrypted pass using the key.
ADDITIONAL THOUGHTS: Maybe obfuscating the Delphi code would be a much better choice?
QUESTION: What is a better way of protecting your password if any?
SOURCES: Here can find the source codes for the FTPTester and OTP generator: Link to both