Recent

Author Topic: [SOLVED] Storing and encrypting/decrypting passwords  (Read 21804 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: Storing and encrypting/decrypting passwords
« Reply #15 on: April 30, 2016, 04:55:04 pm »
Why the hell do you think i want to hash them !!!
And i am experimenting with it to get a better knowledge of it.
Well then. We crossed answers but plz read my reply above . It's from a pro.
Specialize a type, not a var.

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Storing and encrypting/decrypting passwords
« Reply #16 on: April 30, 2016, 05:08:23 pm »
No one have heard of password safe applications? If you have, do you think that password safes use hashes?

madref

  • Hero Member
  • *****
  • Posts: 949
  • ..... A day not Laughed is a day wasted !!
    • Nursing With Humour
Re: Storing and encrypting/decrypting passwords
« Reply #17 on: April 30, 2016, 05:32:29 pm »
@Thaddy: How else to store a password for a mail server.
My program needs to send email to someone and i down want to use a third party program such as outlook.
You treat a disease, you win, you lose.
You treat a person and I guarantee you, you win, no matter the outcome.

Lazarus 3.99 (rev main_3_99-649-ge13451a5ab) FPC 3.3.1 x86_64-darwin-cocoa
Mac OS X Monterey

runs

  • New Member
  • *
  • Posts: 26
Re: Storing and encrypting/decrypting passwords
« Reply #18 on: April 30, 2016, 11:54:12 pm »
In PHP, I have the following system on my working blog engine to store and retrieve passwords and control access.

How can I port to Lazarus, any idea? I suppose I can do it with dcpcrypt.  :D

Store the password:
Code: Pascal  [Select][+][-]
  1. function createSalt() { //creates a 3 character sequence
  2.     $string= md5(uniqid(rand(), true));
  3.     return substr($string, 0, 3);
  4. }
  5. $hash= hash('sha256', $pass1);
  6. $salt= createSalt();
  7. $hash= hash('sha256', $salt . $hash);
  8. $fields= array(
  9.         'user_name' => $username,
  10.         'user_password' => $hash,
  11.         'user_salt' => $salt,
  12.         );
  13. $result= mysql_insert('users', $fields);

Login:
Code: Pascal  [Select][+][-]
  1. $query = "SELECT user_password, user_salt FROM users WHERE username= '$user_name_entered_by_person'"; //get the password & salt of that username entered by anyone
  2. $hash= hash('sha256', $user_salt.hash('sha256', $password_entered_by_person));
  3. if ($hash== $user_password){ //right password
  4.                 $login= TRUE;
  5.         }
  6.  




Projects: LibreStaff

madref

  • Hero Member
  • *****
  • Posts: 949
  • ..... A day not Laughed is a day wasted !!
    • Nursing With Humour
Re: Storing and encrypting/decrypting passwords
« Reply #19 on: May 01, 2016, 12:12:39 am »
No i don't want to store it in my database.
That's redundant in my database.
I want to store it in an option-file like i discussed in this topic


And that is why i want to encrypt en decrypt the password, username and mailserver.
You treat a disease, you win, you lose.
You treat a person and I guarantee you, you win, no matter the outcome.

Lazarus 3.99 (rev main_3_99-649-ge13451a5ab) FPC 3.3.1 x86_64-darwin-cocoa
Mac OS X Monterey

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Storing and encrypting/decrypting passwords
« Reply #20 on: May 01, 2016, 07:06:05 am »
If you want to be able to retrieve the password later on then you can't hash them. You have to use one or two ciphers one on top of the other and depending on the format of your settings file (ee JSON, XML, or binary) a UUncode on the final result. Personally I use two ciphers on on top of the other. Something along the lines of
1) Get encryption password from user
2) Get Login data to be encrypted.
3) create a sault from the user name and other login data.
4) add sault to the encryption password.
5) use 3des to encrypt the login data.
6) reverse encryption password with sault.
7) use rijndael to encrypt the 3des encrypted login data.
6) UUEncode the encrypted data to convert them to string friendly format.
7) append the calculated sault to the end of the encrypted data.
8) Save data.

You can ignore step 6 if you do not save data in a text file but you need to add some short of length of the encrypted data to be able to read them back.
Decryption is the above steps in reverse order
1)Get encryption password
2) load data.
3) get sault from encrypted data.
4) add sault to the password
5) reverse password
6) UUDecode the data
7) decrypt data with rijndael.
8) reverse encryption password again.
9) decrypt data with 3des.
10) use login data.
11) zero out the memory with the unencrypted login data.


runs

  • New Member
  • *
  • Posts: 26
Re: Storing and encrypting/decrypting passwords
« Reply #21 on: May 01, 2016, 01:17:01 pm »
Finally I got it.

I made a unit called "Crypt" with two crypt function to generate a hash from a string password and one salt of 3 chars.
Code: Pascal  [Select][+][-]
  1. unit Crypt;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, DCPsha1;
  9.  
  10. function GenerateSalt(SaltLength: Integer): String;
  11. function HashString(StringToHash: String): String;
  12.  
  13. implementation
  14.  
  15. function HashString(StringToHash: String): String;
  16. var
  17.   Hash: TDCP_sha1;
  18.   Digest: array [1..20] of byte;
  19.   ResultStr: String;
  20.   i: Integer;
  21. begin
  22.   Hash:= TDCP_sha1.Create(nil);
  23.   try
  24.     Hash.Init;
  25.     Hash.UpdateStr(StringToHash); //calculate the hesh-sum
  26.     Hash.Final(Digest);
  27.     for i:=1 to 20 do
  28.       ResultStr:=ResultStr+inttohex(Digest[i],1);
  29.     Result:= ResultStr;
  30.   finally
  31.     Hash.Free;
  32.   end;
  33.  end;
  34.  
  35. function GenerateSalt(SaltLength: Integer): String;
  36. var
  37.   Chars: string;
  38. begin
  39.   Randomize;
  40.   //string with all possible chars
  41.   Chars:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  42.   Result:= '';
  43.   repeat
  44.     Result:= Result + Chars[Random(Length(Chars)) + 1];
  45.   until (Length(Result) = SaltLength)
  46. end;      
  47.  

When I insert a user, I also calculate his password & salt:
Code: Pascal  [Select][+][-]
  1. Salt:= GenerateSalt(SALT_LENGTH);
  2. Password:= Crypt.HashString(Salt+FieldValue);

I have a Login Form, in the Enter Button:
Code: Pascal  [Select][+][-]
  1. procedure TFrmLogin.BtnEnterClick(Sender: TObject);
  2. var
  3.   LoginUser, LoginPassword, HashLoginPassword, HashUser, SaltUser: String;
  4. begin
  5.   LoginUser:= EdiUser.Text;
  6.   LoginPassword:= EdiPassword.Text;
  7.   //Search the user name, password and salt
  8.   FuncData.ExecSQL(DataMod.QueVirtual, 'SELECT ID_User, Hash_User, Salt_User FROM Users WHERE Name_User='''+LoginUser+''' LIMIT 1');
  9.   if DataMod.QueVirtual.IsEmpty= FALSE then
  10.     begin
  11.     SaltUser:= DataMod.QueVirtual.FieldByName('Salt_User').AsString;
  12.     HashLoginPassword:= Crypt.HashString(SaltUser+LoginPassword);
  13.     HashUser:= DataMod.QueVirtual.FieldByName('Hash_User').AsString;
  14.     if (HashLoginPassword= HashUser) then
  15.       begin
  16.       ModalResult:= mrOK;
  17.       end;
  18.     end
  19.   else
  20.     begin
  21.     end;
  22. end;              
« Last Edit: May 01, 2016, 01:19:32 pm by runs »
Projects: LibreStaff

runs

  • New Member
  • *
  • Posts: 26
Re: Storing and encrypting/decrypting passwords
« Reply #22 on: May 01, 2016, 01:24:19 pm »
Now my problem is to raise a PopupNotifier in the password input box of the FormLoginwhen password does not match:

Code: Pascal  [Select][+][-]
  1. procedure TFrmLogin.BtnEnterClick(Sender: TObject);
  2. var
  3.   LoginUser, LoginPassword, HashLoginPassword, HashUser, SaltUser: String;
  4.   p: TPoint;
  5. begin
  6.   LoginUser:= EdiUser.Text;
  7.   LoginPassword:= EdiPassword.Text;
  8.   //Search the user name, password and salt
  9.   FuncData.ExecSQL(DataMod.QueVirtual, 'SELECT ID_User, Hash_User, Salt_User FROM Users WHERE Name_User='''+LoginUser+''' LIMIT 1');
  10.   if DataMod.QueVirtual.IsEmpty= FALSE then
  11.     begin
  12.     SaltUser:= DataMod.QueVirtual.FieldByName('Salt_User').AsString;
  13.     HashLoginPassword:= Crypt.HashString(SaltUser+LoginPassword);
  14.     HashUser:= DataMod.QueVirtual.FieldByName('Hash_User').AsString;
  15.     if (HashLoginPassword= HashUser) then
  16.       begin
  17.       ModalResult:= mrOK;
  18.       end;
  19.     end
  20.   else
  21.     begin
  22. //    p:= Point(EdiUser.Left, EdiUser.Top);
  23. //    p:= FrmLogin.ScreenToClient(p);
  24.       PopLogin.Text:= 'Username does not exist';
  25. //    PopLogin.ShowAtPos(p.x,p.y);
  26.     end;
  27.   //Get the user
  28. end;      
  29.  

How can I get the x and y position of any component of a form to pass to the PopupNotifier?
Projects: LibreStaff

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Storing and encrypting/decrypting passwords
« Reply #23 on: May 01, 2016, 02:23:18 pm »
Salt generation failed, too restrictive. Never restrict your encryption to English characters, in fact make sure that no English characters are used. Use anything else than the well known English/latin characters or use a crypto strong random generator.

madref

  • Hero Member
  • *****
  • Posts: 949
  • ..... A day not Laughed is a day wasted !!
    • Nursing With Humour
Re: Storing and encrypting/decrypting passwords
« Reply #24 on: May 01, 2016, 08:29:50 pm »
I am now using a modified version like this:
Code: Pascal  [Select][+][-]
  1.  
  2. uses
  3.   ..... , DCPrc4, DCPsha256;
  4.  
  5.   procedure TForm1.btnEncryptClick(Sender: TObject);
  6.   var
  7.     i: integer;
  8.     Cipher: TDCP_rc4;
  9.     KeyStr: string;
  10.   begin
  11.     KeyStr:= '';
  12.     if InputQuery('Passphrase','Enter passphrase',KeyStr) then  // get the passphrase
  13.     begin
  14.       Cipher:= TDCP_rc4.Create(Self);
  15.       Cipher.InitStr(KeyStr,TDCP_sha256);         // initialize the cipher with a hash of the passphrase
  16.       for i:= 0 to Memo1.Lines.Count-1 do       // encrypt the contents of the memo
  17.         Memo1.Lines[i]:= Cipher.EncryptString(Memo1.Lines[i]);
  18.       Cipher.Burn;
  19.       Cipher.Free;
  20.     end;
  21.   end;
  22.  
  23.   procedure TForm1.btnDecryptClick(Sender: TObject);
  24.   var
  25.     i: integer;
  26.     Cipher: TDCP_rc4;
  27.     KeyStr: string;
  28.   begin
  29.     KeyStr:= '';
  30.     if InputQuery('Passphrase','Enter passphrase',KeyStr) then  // get the passphrase
  31.     begin
  32.       Cipher:= TDCP_rc4.Create(Self);
  33.       Cipher.InitStr(KeyStr,TDCP_sha256);         // initialize the cipher with a hash of the passphrase
  34.       for i:= 0 to Memo1.Lines.Count-1 do       // decrypt the contents of the memo
  35.         Memo1.Lines[i]:= Cipher.DecryptString(Memo1.Lines[i]);
  36.       Cipher.Burn;
  37.       Cipher.Free;
  38.     end;
  39.   end;
  40.  


Found here.
You treat a disease, you win, you lose.
You treat a person and I guarantee you, you win, no matter the outcome.

Lazarus 3.99 (rev main_3_99-649-ge13451a5ab) FPC 3.3.1 x86_64-darwin-cocoa
Mac OS X Monterey

CuriousKit

  • Jr. Member
  • **
  • Posts: 78
Re: Storing and encrypting/decrypting passwords
« Reply #25 on: May 02, 2016, 04:40:37 am »
This has probably been covered already, but the de facto standard is that passwords are never stored in a way that can be encoded.  Passwords are always passed though a one-way hash function and the result of that algorithm stored on the server.  When a user wishes to log in, they input their password, which is then hashed, and if the result matches what is stored on the server, the user is allowed in.

The use of hashes is far more secure (although the drawback is that if you forget your password, you have to go through a reset process rather than it being given to you) and generally more convenient:

- A hash, being effectively a large, unsigned integer, usually takes less space to store than a (strong) password.
- A good hash betrays no information about the password's length or the characters used.
- If your database is compromised, the hacker only gains access to the hashes, which are useless as they usually cannot be reversed to reveal the users' passwords (it's best to 'salt' the passwords with some prefixed or suffixed symbols to thwart the use of 'rainbow tables').
- Also, because the passwords have to be passed through the same hashing algorithm and the result only revealed once the entire password is processed, this also averts most forms of timing attacks.
- One other thing that many people forget... even if your system is not exactly critical, like it contains no information that could be used to steal a user's identity, their passwords may be the same as those used on other systems; therefore, if they are stored in a reversible form and your system is compromised, then you may cause a user's account to be hacked on a completely independent system because of it using the same password, and it not being stored securely on your system.

Note that you have to use a cryptographically secure hash, so fast hashes like CRC and FNV-1a are unsuitable, as are hashes that are proven to be insecure like MD5.  Today, I would recommend the use of SHA-3 (Keccak).
« Last Edit: May 02, 2016, 04:52:39 am by CuriousKit »

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Storing and encrypting/decrypting passwords
« Reply #26 on: May 02, 2016, 09:30:18 am »
This has probably been covered already, but the de facto standard is that passwords are never stored in a way that can be encoded.  Passwords are always passed though a one-way hash function and the result of that algorithm stored on the server.  When a user wishes to log in, they input their password, which is then hashed, and if the result matches what is stored on the server, the user is allowed in.
It is not a server side password check/authorization. It is a client side one where the program keeps a number of authentication data to be able to automate tasks.

CuriousKit

  • Jr. Member
  • **
  • Posts: 78
Re: Storing and encrypting/decrypting passwords
« Reply #27 on: May 02, 2016, 12:05:44 pm »
Ah right, so the program needs to pass the actual password to a third-party routine or something similar? Makes it a little bit difficult, but I can understand your requirements a little better.

Deepaak

  • Sr. Member
  • ****
  • Posts: 454
Re: Storing and encrypting/decrypting passwords
« Reply #28 on: May 02, 2016, 01:12:26 pm »
Hussh...Sorry, but what a long discussion.

Where there is question regarding storing password only two question is generally asked. That is Secure way or Less Secure way.

Secure Way.
Firstly

1. User Enter Password
2. Hash it
3. Save it.

Secondly
1. User Enter Password
2. Hash it.
3. Compare it.

Less Secure way.
Go for String Encryption and Decryption. But remember no matter how you save the password. It always smells.

Its upto  developers, what kind of security they prefers for their Client. And have a look at good encryption alogrithm and hash

Personal Opinion: Security of Client First.
Holiday season is online now. :-)

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Storing and encrypting/decrypting passwords
« Reply #29 on: May 02, 2016, 01:17:41 pm »
The problem with storing a password for accessing some service is, that the password you used to store the password is in the executable. Someone with a debugger will crack your security in minutes.

Programs that store multiple passwords ask the user for that password.

 

TinyPortal © 2005-2018