3

i've managed to do a simple encryption of a password entered using the following code which then displays the encrypted password in a labels caption,

procedure TfrmLogin.edtAddPasswordClick(Sender: TObject);
var
  NormalPassword, EncryptedPassword: string;
  PasswordChar: Char;
  EncryptedCharValue: string;
  CharPtr: Integer;
  Ptr, n: Integer;
begin
  NormalPassword := Edit1.text;
  EncryptedPassword := '';
  for CharPtr := 1 to Length(NormalPassword) do
  begin
    PasswordChar := NormalPassword[CharPtr];
    EncryptedCharValue := IntToStr (Ord(PasswordChar) * 5 + 14);
    EncryptedPassword := EncryptedPassword + EncryptedCharValue;
    Label1.Caption := EncryptedPassword;
  end;
end;

The problem is that i would like to convert the encrypted password displayed in label1.caption back into its original form on the click of another button and i can't work out how this could be done. any suggestions?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Jeowkes
  • 501
  • 7
  • 20
  • 6
    Generally, passwords are hashed, not encrypted. And you can't reverse a hash. – Oliver Charlesworth Apr 09 '12 at 20:12
  • 1
    That algorithm cannot be reversed – David Heffernan Apr 09 '12 at 20:16
  • 1
    Oli's right in principle, although I can see that there are some cases you'd want this reversible; for example, a password storage app. In that case, though, you'd perhaps want to use a stronger algorithm, and a key selected by the user – Geoff Apr 09 '12 at 20:17
  • @DavidHeffernan, what you mean with `..cannot be reversed`? – RRUZ Apr 09 '12 at 20:32
  • I appreciate the suggestions but unfortunately this is part of an A level project of mine and marks are not awarded unless the algorithm is made by myself, but yes if this was going to be used by a real end user i would use a stronger algorithm – Jeowkes Apr 09 '12 at 20:33
  • @RRUZ Different input strings can results in the same output values. Mathematically speaking, it is not an injection. – David Heffernan Apr 09 '12 at 20:34
  • You should have said up-front that you were asking us to help you do your A level project. I have now tagged it as such. – David Heffernan Apr 09 '12 at 20:35
  • @DavidHeffernan, Indeed, I thought that you are saying that is not possible get the original string back :) – RRUZ Apr 09 '12 at 20:38
  • @DavidHeffernan, can you explain how different strings result in the same output? – Geoff Apr 09 '12 at 20:40
  • @RRUZ I don't think it is possible to do that. – David Heffernan Apr 09 '12 at 20:40
  • oh sorry i didn't know there was such a tag, i must point out that the marks are awarded for the encryption of the password which i had already done, the code i'm requesting is not going to be included. – Jeowkes Apr 09 '12 at 20:40
  • @RRUZ It can be reversed so long as the input was constrained to be between chr(18) and chr(198). Otherwise you can construct distinct inputs that lead to the same output. – David Heffernan Apr 09 '12 at 20:50

5 Answers5

6

Instead of create your own algorithm to hash( or encrypt) a password, try using a well tested and reliable algorithm like SHA1, MD5, and so on.

Back to your question to convert the encrypted value to the original, all you must do is reverse your algorithm , try this sample.

var
  NormalPassword, EncryptedPassword: String;
  PasswordChar : char;
  EncryptedCharValue : String;
  CharPtr : Integer;
begin
  NormalPassword    :='';
  EncryptedPassword := Label1.Caption; //here is stored the encrypted password
  CharPtr := 1;
  while CharPtr< length(EncryptedPassword) do
    Begin
      EncryptedCharValue:=Copy(EncryptedPassword, CharPtr, 3);
      Inc(CharPtr, 3);
      PasswordChar     := Chr((StrToint(EncryptedCharValue)-14) div 5);
      NormalPassword  :=NormalPassword+ PasswordChar;
    end;
    Label2.Caption := NormalPassword; 
end;
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • chr(198) maps to a 4 digit value so this code does not work. And there are inputs that map to 2 digit values. – David Heffernan Apr 09 '12 at 20:46
  • @DavidHeffernan this is just a homework for the OP, the original algorithm is not a military-grade encryption. so the answer is as good or as bad as the original algorithm. – RRUZ Apr 09 '12 at 20:49
  • I was just continuing the conversation about whether or not the algo can be reversed. – David Heffernan Apr 09 '12 at 20:50
  • this works for the purpose of my homework, i was wondering whether you could explain these 2 lines of code EncryptedCharValue:=Copy(EncryptedPassword, CharPtr, 3); Inc(CharPtr, 3); – Jeowkes Apr 09 '12 at 20:57
  • @user What do you think they do? What did your study of the documentation tell you about the Copy function? And what about the `inc` function. – David Heffernan Apr 09 '12 at 20:58
  • 2
    [Copy](http://docwiki.embarcadero.com/VCL/en/System.Copy) and [Inc](http://docwiki.embarcadero.com/VCL/en/System.Inc) – RRUZ Apr 09 '12 at 21:00
  • 2
    [`copy`](http://docwiki.embarcadero.com/VCL/en/System.Copy), [`inc`](http://docwiki.embarcadero.com/VCL/en/System.Inc) – Andreas Rejbrand Apr 09 '12 at 21:00
  • I meant why is the substring returned 3 characters long? – Jeowkes Apr 09 '12 at 21:05
  • @user Follow the identical links that RRUZ and Andreas gave you and you will see why it is 3 chars long – David Heffernan Apr 09 '12 at 21:08
  • @user1277240 Because each the `ord` value of each char between #18 and #197 multiply by 5 plus 14 produces a value of 3 digits. – RRUZ Apr 09 '12 at 21:09
  • @RRUZ It would be nice if you could just add something to your answer to state the #18..#197 limit and then I'd stop nagging you!! ;-) – David Heffernan Apr 09 '12 at 21:12
  • 2
    @DavidHeffernan give some minutes, i'm using a Android Phone with a old browser now, and is very difficult to edit the questions ;) – RRUZ Apr 09 '12 at 21:17
4

I know this is for homework and the idea is to get the reversing code, and others are providing you too much detail for that purpose, but I need to give this as an answer because its concept is too important to say in a note:

If you are truly talking about a password, then you must not make the password reversable. Users expect their passwords to be safe and secure and non-reversable.

If the reason why you want to do this is because you want to send them their password if they forget it, then the answer is don't.

When a person loses or forgets their password, you should not provide it back to them, because that proves it is insecure. Instead, the proper thing to do is, after ensuring they are the user who signed up (via email address or other means), then allow them to enter a new password of their choice.

lkessler
  • 19,819
  • 36
  • 132
  • 203
2

If you're determined to do it the way you've described, you could make it reversible by changing the line:

EncryptedCharValue := IntToStr (Ord(PasswordChar) * 5 + 14);

to

EncryptedCharValue := format('%.4d', [Ord(PasswordChar) * 5 + 14]);

That would allow you later to pull the string apart in four-character chunks, subtract 14, divide by 5, and turn it back into a character. I stand by my earlier comment though - if you actually have a use-case that requires reversible security, use a stronger algorithm, for example as discussed in this question.

[Edit: four chars is clearly more robust]

Community
  • 1
  • 1
Geoff
  • 8,551
  • 1
  • 43
  • 50
1

You function is a very simple hashing algorithm that cannot be reversed. It does not make sense to store passwords in a way that can be reversed, since it does not add any additional layer of security (except you use a complicated scheme based on asymmetric crypto)

mensi
  • 9,580
  • 2
  • 34
  • 43
0

simple hash algorithm : How do I hash a string with Delphi?

hash with secret key algorithm(CRAM,HMac): HMAC-SHA256 in Delphi

Community
  • 1
  • 1
MajidTaheri
  • 3,813
  • 6
  • 28
  • 46