How to implement pbkdf2_sha256 in c#

6.1k views Asked by At

I have made a website, in which on login I am using pbkdf2_sha256 for password hashing. I have used salt also. I want to make a simple software just for the experience, I want to login into the c# software using same credentials as saved by the website. I have seen Rfc2898DeriveBytes I guess it only takes 2 arguments (password, salt in integer). But what about iterations I have specified on the website?

Anyone, please guide me how to make a login in c# (WPF) application and use pbkdf2_sha256 to create a hash and to verify the password.

I have seen a code given on stacksoverflow.com.

var salt = "FbSnXHPo12gb";
var password = "geheim";

var interactions = 12000;


using (var hmac = new HMACSHA256())
{
    var df = new Pbkdf2(hmac, password, salt, interactions);
    Console.WriteLine(Convert.ToBase64String(df.GetBytes(32)));
}

I used this also but it is giving error in var df = new Pbkdf2(hmac, password, salt, interactions); Pbkdf2 could not found.

my code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MySql.Data.MySqlClient;
using System.IO;
using System.Security.Cryptography;


namespace login
{

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
        }

        private void login_Click(object sender, RoutedEventArgs e)
        {

            var salt = "FbSnXHPo12gb";
            var password = "geheim";
            var interactions = 12000;


            using (var hmac = new HMACSHA256())
            {
                var df = new Pbkdf2(hmac, password, salt, interactions);
                Console.WriteLine(Convert.ToBase64String(df.GetBytes(32)));
            }

            string myConnection = "datasource=localhost;port=3306;username=root;password=abcde12345 ; database=finalproject";
            MySqlConnection myConn = new MySqlConnection(myConnection);
            MySqlCommand SelectCommand = new MySqlCommand("select * from login where Username='" + this.username.Text + "' and Password='" + this.password.Password + "';", myConn);
            MySqlDataReader myReader;
            myConn.Open();
            myReader = SelectCommand.ExecuteReader();
            int count = 0;
            while (myReader.Read())
            {
                count = count + 1;
            }
            if (count == 1)
            {
                MessageBox.Show("Hello");

            }

            else
            {

                MessageBox.Show("Wrong username and password");
            }
            myConn.Close();
        }
    }
}

So please tell me which hashing algorithm I should use on the server which is good for a password. I have read about bcrypt and scyrpt. Are they good for password hashing? Actually, I am not decrypting I am only hashing password in software and then comparing hash stored on server with the hash generated in software

please help me. Sorry for mistakes.

2

There are 2 answers

9
bartonjs On BEST ANSWER

The Pbkdf2 class you found elsewhere on StackOverflow is not part of .NET, so to use it you'd need to obtain the library it's in.

In order to do PBKDF2 with (HMAC-)SHA-2-256, you would need at least .NET Core 2.0 or .NET Framework 4.7.2.

Either way you need to turn your salt into bytes. Since it's a multiple of 4 characters I'm going to assume it's base64:

byte[] saltBytes = Convert.FromBase64String(salt);
byte[] derived;

.NET Framework (2.0+) (HMAC-SHA-1):

using (var pbkdf2 = new Rfc2898DeriveBytes(password, saltBytes, interactionCount))
{
    derived = pbkdf2.GetBytes(32);
}

.NET Core (2.0+), .NET Framework (4.7.2+) (using HMAC-SHA-2-256):

using (var pbkdf2 = new Rfc2898DeriveBytes(
    password,
    saltBytes,
    interactionCount,
    HashAlgorithmName.SHA256))
{
    derived = pbkdf2.GetBytes(32);
}

If you need to use something other than (HMAC-)SHA-1 in .NET Framework you'll need to upgrade to 4.7.2.

API Docs:

3
Mateus Custodio On

Well, there is a fully working example here in MSDN.

But, if your purpose is really hash a password, I would not advise you to do it like that.

There is no need to decrypt your passwords.

It's much easier and safer if you just use the SHA256 algorithm. All you need to do is store the hashed password in your database and when someone attempt to login into your website you will hash the given password and compare with the value stored in your database.

Doing this you have a one way encryption, so there is no way to decrypt your passwords.

Why? If your application have been hacked, the attackers can't decrypt the stored passwords so they can't login.

There is a example on how to hash using SHA256 here. Really, it's much easier.