Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: Cryptography Programming Question  (Read 4429 times)

0 Members and 1 Guest are viewing this topic.

TheWaffle

    Topic Starter


    Hopeful
  • Thanked: 4
    • Yes
  • Computer: Specs
  • Experience: Beginner
  • OS: Linux variant
Cryptography Programming Question
« on: October 21, 2016, 08:40:10 PM »
Sorry in advance: I wasn't sure where to post this.

So my situation is: I have a password for a user and I want to store an encrypted version of the password in a database. 

I was doing some reading and was overwhelmed by all the different ways to encrypt things.
All I want want to do is encrypt a password in such a way that it does not have a key to decrypt it.  (I have no need to decrypt it, I plan on just encrypting the password again and checking to see if they match)

One of the articals I read, and found easy to read was here: https://crackstation.net/hashing-security.htm
Now I don't fully trust this artical because it left out details not mentioned in others and the author promoted his own library.  I don't want to use his library I just want to understand what needs to be done to encrypt a password in the way I have described.

I'm using .net btw.

Am I on the right track?

Code: [Select]
//TODO Come back and catch exceptions
public static byte[] generateSalt(){
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
byte[] ben = new byte[32];
rng.GetNonZeroBytes(ben);
return ben;
}
//TODO Come back and catch exceptions
public static string hashPassword(string password, byte[] salt){
System.Security.Cryptography.Rfc2898DeriveBytes rfc = new System.Security.Cryptography.Rfc2898DeriveBytes(password,salt);
System.Security.Cryptography.Ri+
byte[] key = rfc.CryptDeriveKey("TripleDES","SHA1",0,iv);
string res = System.Text.Encoding.ASCII.GetString(key);
return res;
}

Geek-9pm


    Mastermind
  • Geek After Dark
  • Thanked: 1026
    • Gekk9pm bnlog
  • Certifications: List
  • Computer: Specs
  • Experience: Expert
  • OS: Windows 10
Re: Cryptography Programming Question
« Reply #1 on: October 21, 2016, 10:40:40 PM »
Quote
All I want want to do is encrypt a password in such a way that it does not have a key to decrypt it.  (I have no need to decrypt it, I plan on just encrypting the password again and checking to see if they match)

Before yo go any  deeper, please clarify the above statement. A password i just 8to 16 characters long. There is little need for heavy duty encryption. Yet there should be some way to verify the hash with the original.

And you do not need to write the code. Others have already don it. In Java there already are things for doing that kind of stuff. Same in C++ and Visual Basic.

BC_Programmer


    Mastermind
  • Typing is no substitute for thinking.
  • Thanked: 1140
    • Yes
    • Yes
    • BC-Programming.com
  • Certifications: List
  • Computer: Specs
  • Experience: Beginner
  • OS: Windows 11
Re: Cryptography Programming Question
« Reply #2 on: October 22, 2016, 01:31:29 AM »
Generate a Random Salt. Use a new salt each time a hash is computed.

Code: [Select]
public static byte[] GenerateSalt()
{
    byte[] salt = new byte[16];
    new RNGCryptoServiceProvider().GetBytes(salt);
    return salt;
}

hash a password with a salt into a Base64 string for storing into a database (or wherever)

Code: [Select]
public static String HashPassword(string password, byte[] salt)
{
    var hasher = new Rfc2898DeriveBytes(password, salt, 10000);
    byte[] hash = hasher.GetBytes(20);
    byte[] hashBytes = new byte[36];
    Array.Copy(salt, 0, hashBytes, 0, 16);
    Array.Copy(hash, 0, hashBytes, 16, 20);
    return Convert.ToBase64String(hashBytes);
}

Verify that a password matches a hash. You could alternatively also use HashPassword() with the same salt stored elsewhere or from other data and compare the output. This uses the Salt present in the original Hash and checks if the provided password matches instead:

Code: [Select]
public static bool VerifyPassword(String password,String StoredHash)
        {
           
            byte[] hashBytes = Convert.FromBase64String(StoredHash);
            byte[] salt = new byte[16];
            Array.Copy(hashBytes, 0, salt, 0, 16);
            var hasher = new Rfc2898DeriveBytes(password, salt, 10000);
            byte[] hash = pbkdf2.GetBytes(20);
            for (int i = 0; i < 20; i++)
                if (hashBytes[i + 16] != hash[i])
                    return false;
            return true;
        }
I was trying to dereference Null Pointers before it was cool.