PBKDF2 (“Password-Based Key Derivation Function 2”) ist eine der empfohlenen Hash Funktion für Passwort Hashing – ist Teil von rfc-2898.

Anwendungsmöglichkeiten:

Aus einem Passwort (Text) und einem zufälligen Salt werden beliebig lange binäre Keys (bzw. auch Random-IV und MAC-Key falls benötigt).

Frage: Wie lange soll das Salt sein und wie viele Iterationen. Salted Password Hashing - Doing it Right

PBKDF2 verwendet eine Hash Funktion, für diesen Fall ist auch SHA-1 (trotz der bekannten Kollisionen) in Ordnung [Quelle-stackoverflow].


Übung (PBKDF2)

Verwende die .NET core Library (Rfc2898DeriveBytes) um den Hashwert (in Base64 Format) eines als String vorgegebenen Passworts zu ermitteln. Der Hashwert soll 256 Bits lang sein. Verwende RNGCryptoServiceProvider um dafür ein zufälliges Salt mit 64 Bits zu erzeugen. Die Anzahl der Iterationen ist so zu wählen, dass das generieren des Hashwerts ca. 200 ms benötigt.

Schreibe nach ersten Tests ein Programm das über einen Kommandozeilenschalter gesteuert 2 Modi anbietet:

Hinweise – User Input:


Lösung Grundlage:

using System;
using System.Security.Cryptography;

namespace crypt02keyderivation
{
    class Program
    {
        static void Main(string[] args)
        {
            string pwd = "mypassword";

            // Create a byte array to hold the random value using a cryptographic Random Number Generator (RNG).
            // [RNGCryptoServiceProvider Class](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rngcryptoserviceprovider?view=netcore-3.1)
            byte[] salt = new byte[8]; // 64 Bit salt
            using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider()){
            	rngCsp.GetBytes(salt);
            }
            //byte[] salt = {0,0,0,0,0,0,0,0};
            System.Console.WriteLine("Salt: "+System.Convert.ToBase64String(salt));

            // create object for PBKDF2 functionality
            Rfc2898DeriveBytes derived_key = new Rfc2898DeriveBytes(pwd, salt, iterations: 100000);
          	System.Console.WriteLine(derived_key.HashAlgorithm); // SHA1 = 160-bit (20-byte) hash value


            // [Rfc2898DeriveBytes.GetBytes(Int32) Method](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes.getbytes?view=netcore-3.1#System_Security_Cryptography_Rfc2898DeriveBytes_GetBytes_System_Int32_)

            // The Rfc2898DeriveBytes class implements PBKDF2 functionality by using a pseudorandom number generator based on HMACSHA1. The Rfc2898DeriveBytes class takes a password, a salt, and an iteration count, and then generates keys through calls to the GetBytes method. **Repeated calls to this method** will not generate the same key; instead, appending two calls of the GetBytes method with a cb parameter value of 20 is the equivalent of calling the GetBytes method once with a cb parameter value of 40.

            byte[] key = derived_key.GetBytes(32); // 256 Bits
            System.Console.WriteLine(System.Convert.ToBase64String(key));

            // in case we need an IV and/or MAC-key
            key = derived_key.GetBytes(32); // another (different) 256 Bits
            System.Console.WriteLine(System.Convert.ToBase64String(key));

            // because we use a random salt, these values changes (would not if salt=0)

        }
    }
}