mirror of
https://github.com/KeyKeeperApp/KeyKeeper.git
synced 2026-04-17 18:16:28 +03:00
add class for password-based key derivation
This commit is contained in:
42
src/KeyKeeper/PasswordStore/Crypto/KeyDerivation/AesKdf.cs
Normal file
42
src/KeyKeeper/PasswordStore/Crypto/KeyDerivation/AesKdf.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace KeyKeeper.PasswordStore.Crypto.KeyDerivation;
|
||||
|
||||
public class AesKdf : MasterKeyDerivationFunction
|
||||
{
|
||||
public const int MIN_ROUNDS = 10;
|
||||
public const int MAX_ROUNDS = 25_000_000;
|
||||
public const int SEED_LENGTH = 32;
|
||||
|
||||
private int rounds;
|
||||
private byte[] seed;
|
||||
|
||||
public AesKdf(int rounds, byte[] seed)
|
||||
{
|
||||
if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS)
|
||||
throw new ArgumentOutOfRangeException(nameof(rounds));
|
||||
if (seed.Length != SEED_LENGTH)
|
||||
throw new ArgumentException("seed length must be " + SEED_LENGTH);
|
||||
this.rounds = rounds;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public override byte[] Derive(CompositeKey source, int keySizeBytes)
|
||||
{
|
||||
if (keySizeBytes > SEED_LENGTH)
|
||||
throw new ArgumentOutOfRangeException(nameof(keySizeBytes));
|
||||
|
||||
byte[] key = source.Hash()[..SEED_LENGTH];
|
||||
byte[] nextKey = new byte[SEED_LENGTH];
|
||||
Aes cipher = Aes.Create();
|
||||
cipher.KeySize = SEED_LENGTH;
|
||||
for (int i = 0; i < rounds; ++i)
|
||||
{
|
||||
cipher.Key = key;
|
||||
cipher.EncryptEcb(seed, nextKey, PaddingMode.None);
|
||||
(nextKey, key) = (key, nextKey);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace KeyKeeper.PasswordStore.Crypto;
|
||||
|
||||
public abstract class MasterKeyDerivationFunction
|
||||
{
|
||||
public abstract byte[] Derive(CompositeKey source, int keySizeBytes);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Security.Cryptography;
|
||||
using KeyKeeper.PasswordStore.Crypto.KeyDerivation;
|
||||
|
||||
namespace KeyKeeper.PasswordStore;
|
||||
|
||||
@@ -6,8 +7,8 @@ static class FileFormatConstants
|
||||
{
|
||||
public const int MIN_MASTER_SALT_LEN = 8;
|
||||
public const int MAX_MASTER_SALT_LEN = 40;
|
||||
public const int MIN_AESKDF_ROUNDS = 10;
|
||||
public const int MAX_AESKDF_ROUNDS = 65536;
|
||||
public const int MIN_AESKDF_ROUNDS = AesKdf.MIN_ROUNDS;
|
||||
public const int MAX_AESKDF_ROUNDS = AesKdf.MAX_ROUNDS;
|
||||
public const byte ENCRYPT_ALGO_AES = 14;
|
||||
public const byte KDF_TYPE_AESKDF = 195;
|
||||
public const int HMAC_SIZE = HMACSHA3_512.HashSizeInBytes;
|
||||
|
||||
Reference in New Issue
Block a user