Skip to content

Commit

Permalink
Increase PBKDF2 iterations
Browse files Browse the repository at this point in the history
  • Loading branch information
lellis1936 committed May 5, 2022
1 parent 7e16212 commit cbb03d7
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 12 deletions.
34 changes: 23 additions & 11 deletions GcmCrypt/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ class Program
const int KEY_LENGTH = 32;
const int TAG_LENGTH = 16;
const int SALT_LENGTH = 16;
const int V1_1_HEADER_LENGTH = 74;
const int V1_HEADER_LENGTH = 74;

static readonly byte[] HEADER_NONCE = Enumerable.Repeat((byte)0xff, NONCE_LENGTH).ToArray();
static readonly byte[] FEK_NONCE = Enumerable.Repeat((byte)0x00, NONCE_LENGTH).ToArray();
static readonly byte[] NO_DATA = new byte[0];

const byte VERSION_MAJOR = 1;
const byte VERSION_MINOR = 1;
const byte VERSION_MINOR = 2;
static void Main(string[] args)
{
bool encrypting = false;
Expand Down Expand Up @@ -93,7 +93,9 @@ static void Main(string[] args)

static void PrintUsage()
{
Console.WriteLine("GcmCrypt usage is : ");
string version = VERSION_MAJOR.ToString() + "." + VERSION_MINOR.ToString();
Console.WriteLine($"GcmCrypt v{version}");
Console.WriteLine("Usage is : ");
Console.WriteLine("\tGcmCrypt -e|-d [-f] [-compress] password infile outfile. ");
Console.WriteLine();
Console.WriteLine("Examples:");
Expand All @@ -113,16 +115,20 @@ private static void EncryptFile(string password, string inputFile, string output

var rng = RNGCryptoServiceProvider.Create();


var sig = Encoding.UTF8.GetBytes("GCM");
var salt = new byte[SALT_LENGTH];
var key2 = new byte[KEY_LENGTH];
var key2Encrypted = new byte[KEY_LENGTH];
rng.GetBytes(salt);
rng.GetBytes(key2);

Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA256);
sw.Start();
Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(password, salt, 100000, HashAlgorithmName.SHA256);
byte[] key1 = k1.GetBytes(32);

Console.WriteLine($"Key derivation took {sw.ElapsedMilliseconds} ms");

byte[] key2EncryptedTag = new byte[TAG_LENGTH];
key2Encrypted = GcmEncrypt(key2, key1, FEK_NONCE, key2EncryptedTag);

Expand Down Expand Up @@ -159,7 +165,7 @@ private static void EncryptFile(string password, string inputFile, string output
using (var ms = new MemoryStream())
using (GZipStream gstr = compression ? new GZipStream(ms, CompressionMode.Compress, true) : null)
{
sw.Start();
sw.Restart();
if (compression)
{
fsIn.CopyTo(gstr);
Expand Down Expand Up @@ -199,25 +205,29 @@ private static void DecryptFile(string password, string inputFile, string output
var key2EncryptedTag = new byte[TAG_LENGTH];
var compressed = new byte[1];
var BEchunkSize = new byte[4];
int PBKDF2iterations;

int headerLength;
var headerTag = new byte[TAG_LENGTH];

fsIn.ForceRead(sig, 0, sig.Length);
fsIn.ForceRead(versionMajor, 0, versionMajor.Length);
fsIn.ForceRead(versionMinor, 0, versionMinor.Length);

if (!sig.SequenceEqual(expectedSig)
|| versionMajor[0] != 1
|| versionMinor[0] != 1)
|| (versionMajor[0] != 1)
|| (versionMinor[0] != 1 && versionMinor[0] != 2))
{
Console.WriteLine("Unsupported input file version");
return;
}
else
{
headerLength = V1_1_HEADER_LENGTH;
headerLength = V1_HEADER_LENGTH;
}

PBKDF2iterations = versionMinor[0] == 1 ? 10000 : 100000;

//Read in rest of V1.0 header pieces
fsIn.ForceRead(salt, 0, salt.Length);
fsIn.ForceRead(key2Encrypted, 0, key2Encrypted.Length);
Expand All @@ -231,8 +241,10 @@ private static void DecryptFile(string password, string inputFile, string output
fsIn.ForceRead(header, 0, headerLength);
fsIn.ForceRead(headerTag, 0, headerTag.Length);

Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA256);
sw.Start();
Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(password, salt, PBKDF2iterations, HashAlgorithmName.SHA256);
byte[] key1 = k1.GetBytes(32);
Console.WriteLine($"Key derivation took {sw.ElapsedMilliseconds} ms");

GcmDecrypt(NO_DATA, key1, HEADER_NONCE, headerTag, header);

Expand All @@ -245,7 +257,7 @@ private static void DecryptFile(string password, string inputFile, string output
using (var ms = new MemoryStream())
using (GZipStream gstr = compression ? new GZipStream(ms, CompressionMode.Decompress) : null)
{
sw.Start();
sw.Restart();
if (compression)
{
ChunkedDecrypt(key2, chunkSize, fsIn, ms);
Expand All @@ -257,7 +269,7 @@ private static void DecryptFile(string password, string inputFile, string output
ChunkedDecrypt(key2, chunkSize, fsIn, fsOut);
}
sw.Stop();
Console.WriteLine("File decrypted. AES GCM decryption took {0} ms", sw.ElapsedMilliseconds);
Console.WriteLine("File decrypted successfully. AES GCM decryption took {0} ms.", sw.ElapsedMilliseconds);
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ This program offers ultra-high speed file encryption from the command-line. Thi

The CNG library for Windows Vista and later leverages hardware-assisted encryption available on modern Intel processor for GCM encryption.

## Version History


- 5/5/2022. v1.2 Increase PBKDF2 iterations to 100,000.
- 8/1/2019. v1.1 First version.


## Execution Requirements
- .Net 4.8 (available on the latest Windows 10 release or it can be downloaded)
Expand Down Expand Up @@ -45,7 +51,7 @@ Each encrypted file begins with the following file header:

3 bytes - 'GCM'
1 byte - 0x01 (Version Major)
1 byte - 0x01 (Version Minor)
1 byte - 0x02 (Version Minor)
16 bytes - Salt for PBKDF2 key derivation
32 bytes - GCM-encrypted file encryption key (EFEK)
16 bytes - GCM tag for GCM-encrypted AES key
Expand Down

0 comments on commit cbb03d7

Please sign in to comment.