2

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.

  • Maybe I'm mistaked but isn't "Pbkdf2" all in lower case? probably could mean the reason it didn't found it. – Tridam Sep 05 '17 at 20:11
  • 1
    The particularly PBKDF2 implementation you're referencing is only available in .NET Core, not in the full .NET framework. To use PBKDF2 in the framework, you're looking for System.Security.Cryptography.Rfc2898DeriveBytes instead. It does have a ctor overload that allows you to specify the number of iterations. – Xander Sep 05 '17 at 22:58
  • Xander is right. Rfc2898DeriveBytes is the class you want. Either that or search for a NuGet package that implements an [Argon2](https://password-hashing.net/) binding, as Argon2 is the current state-of-the-art. – Polynomial Sep 05 '17 at 23:52
  • 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. – Minato Namikaze Sep 06 '17 at 04:50
  • System.Security.Cryptography.Rfc2898DeriveBytes this is a namespace, I have used this but the error remains the same. – Minato Namikaze Sep 06 '17 at 04:52

2 Answers2

4

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:

bartonjs
  • 30,352
  • 2
  • 71
  • 111
  • I am using salt like " fQ6x8I****** " . I got an idea from ur post, can you tell me which references to add to make the code working. If you could type a little program just to generate pbkdf2_sha256 hash for the demonstration that will be really helpful to me. I am new to this. @@@@ Thanks for reply it was really helpfull@@@@ – Minato Namikaze Sep 06 '17 at 15:53
  • I tried the code you have given I am getting error Error CS1729 'Rfc2898DeriveBytes' does not contain a constructor that takes 4 arguments – Minato Namikaze Sep 06 '17 at 16:12
  • You need to be using .NET Core 2.0 and compiling against the `netcoreapp20` TFM to use the new 4-argument constructor. – bartonjs Sep 06 '17 at 16:20
  • Sorry, I am new to it........ is .Net Core 2.0 is a NuGet package? ...........and what it means compiling against the netcoreapp20?... ok got it .net core 2.0 is a.net version am i right?...thanks for reply – Minato Namikaze Sep 06 '17 at 16:48
  • i installed .Net core 2.0 .......but is not showing any options in the menu where i can change my .NET framework version (properties of my project). Is it available for WPF applications? If it is then ho to use it. i have less time to complete it please help. @@@@@@@@@@thank you@@@ – Minato Namikaze Sep 07 '17 at 05:11
  • I believe that .NET Core is currently limited to command-line and web experiences, no WPF or WinForms or other UI libraries are present. If the .NET Core [source license](https://github.com/dotnet/corefx/blob/master/LICENSE.TXT) is acceptable to your project you could always try pulling [the code](https://github.com/dotnet/corefx/blob/release/2.0.0/src/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs) in locally. – bartonjs Sep 07 '17 at 15:39
  • Copying the source, implementing it from the spec (https://tools.ietf.org/html/rfc2898#section-5.2), or finding a 3rd party library. But as I said in the answer, .NET Framework does not have it built in. – bartonjs Sep 07 '17 at 17:49
  • i found PBKDF2.NET a NuGet package but I am not getting how to use it – Minato Namikaze Sep 07 '17 at 17:51
  • The new constructors shipped in .NET 4.7.2, updated the answer. – bartonjs Jun 30 '18 at 17:40
1

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.

  • 3
    PBKDF2 does result in a hash. SHA256 is much too fast, and not suitable for hashing passwords. – Xander Sep 05 '17 at 22:55
  • 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? – Minato Namikaze Sep 06 '17 at 04:46
  • actually, my hashing is a combination of pbkdf2_sha256 its on particularly one algorithm, I guess. – Minato Namikaze Sep 06 '17 at 04:58