mirror of
https://github.com/KeyKeeperApp/KeyKeeper.git
synced 2026-05-02 12:56:31 +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 System.Security.Cryptography;
|
||||||
|
using KeyKeeper.PasswordStore.Crypto.KeyDerivation;
|
||||||
|
|
||||||
namespace KeyKeeper.PasswordStore;
|
namespace KeyKeeper.PasswordStore;
|
||||||
|
|
||||||
@@ -6,8 +7,8 @@ static class FileFormatConstants
|
|||||||
{
|
{
|
||||||
public const int MIN_MASTER_SALT_LEN = 8;
|
public const int MIN_MASTER_SALT_LEN = 8;
|
||||||
public const int MAX_MASTER_SALT_LEN = 40;
|
public const int MAX_MASTER_SALT_LEN = 40;
|
||||||
public const int MIN_AESKDF_ROUNDS = 10;
|
public const int MIN_AESKDF_ROUNDS = AesKdf.MIN_ROUNDS;
|
||||||
public const int MAX_AESKDF_ROUNDS = 65536;
|
public const int MAX_AESKDF_ROUNDS = AesKdf.MAX_ROUNDS;
|
||||||
public const byte ENCRYPT_ALGO_AES = 14;
|
public const byte ENCRYPT_ALGO_AES = 14;
|
||||||
public const byte KDF_TYPE_AESKDF = 195;
|
public const byte KDF_TYPE_AESKDF = 195;
|
||||||
public const int HMAC_SIZE = HMACSHA3_512.HashSizeInBytes;
|
public const int HMAC_SIZE = HMACSHA3_512.HashSizeInBytes;
|
||||||
|
|||||||
Reference in New Issue
Block a user