Merge pull request #9 from h5p9sl/master

Added file metadata, and randomized initialization vectors.
This commit is contained in:
Alexander 2018-11-24 18:23:11 +02:00 committed by GitHub
commit 6f21bb09b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 132 additions and 24 deletions

View file

@ -5,17 +5,95 @@
namespace Crypto_Notepad namespace Crypto_Notepad
{ {
/// <summary>
/// This class extracts information needed for decryption from a .cnp file
/// </summary>
class AESMetadata
{
/// <summary>
/// Offset to actual AES data; size of metadata
/// </summary>
private int _offsetToData;
public int offsetToData
{
get
{
return this._offsetToData;
}
}
private byte[] _initialVector;
public byte[] initialVector
{
get
{
return this._initialVector;
}
}
private byte[] _salt;
public byte[] salt
{
get
{
return this._salt;
}
}
public AESMetadata()
{
this._initialVector = new byte[16];
this._salt = null;
}
public void DeleteMetadataFromBuffer(ref byte[] rawData)
{
// Possibly unsafe
byte[] buffer = new byte[rawData.Length - this.offsetToData];
System.Buffer.BlockCopy(rawData, this.offsetToData, buffer, 0, rawData.Length - this.offsetToData);
rawData = buffer;
}
public void GetMetadata(byte[] rawData)
{
int index = 0;
// Read initialVector
for (int i = 0; index < rawData.Length; index++, i++)
{
if (rawData[index] == '\0') // Null terminator
{
index++;
break;
}
this.initialVector[i] = rawData[index];
}
// This is kind of a dirty fix, but it gets the job done
// Get length of salt
int length = 0;
for (int i = index; i < rawData.Length; i++)
{
if (rawData[i] == '\0') // Null terminator
{
index++;
break;
}
length++;
}
// Copy bytes into this.salt
this._salt = new byte[length];
System.Buffer.BlockCopy(rawData, index - 1, this.salt, 0, length);
this._offsetToData = this.salt.Length + 1 + this.initialVector.Length + 1;
}
}
class AES class AES
{ {
public static string Encrypt(string plainText, string password, public static string Encrypt(string plainText, string password, byte[] initialVectorBytes,
string salt = "Kosher", string hashAlgorithm = "SHA1", string salt = "Kosher", string hashAlgorithm = "SHA1",
int passwordIterations = 2, string initialVector = "OFRna73m*aze01xY", int passwordIterations = 2, int keySize = 256)
int keySize = 256)
{ {
if (string.IsNullOrEmpty(plainText)) if (string.IsNullOrEmpty(plainText))
return ""; return "";
byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt); byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
@ -28,10 +106,16 @@ public static string Encrypt(string plainText, string password,
byte[] cipherTextBytes = null; byte[] cipherTextBytes = null;
using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor using (MemoryStream memStream = new MemoryStream())
(keyBytes, initialVectorBytes))
{ {
using (MemoryStream memStream = new MemoryStream()) byte[] nullByte = { 0 };
memStream.Write(initialVectorBytes, 0, initialVectorBytes.Length);
memStream.Write(nullByte, 0, 1);
memStream.Write(saltValueBytes, 0, saltValueBytes.Length);
memStream.Write(nullByte, 0, 1);
using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor
(keyBytes, initialVectorBytes))
{ {
using (CryptoStream cryptoStream = new CryptoStream using (CryptoStream cryptoStream = new CryptoStream
(memStream, encryptor, CryptoStreamMode.Write)) (memStream, encryptor, CryptoStreamMode.Write))
@ -45,24 +129,31 @@ public static string Encrypt(string plainText, string password,
} }
} }
symmetricKey.Clear(); symmetricKey.Dispose();
return Convert.ToBase64String(cipherTextBytes); return Convert.ToBase64String(cipherTextBytes);
} }
public static string Decrypt(string cipherText, string password, public static string Decrypt(string cipherText, string password,
string salt = "Kosher", string hashAlgorithm = "SHA1", string hashAlgorithm = "SHA1",
int passwordIterations = 2, string initialVector = "OFRna73m*aze01xY", int passwordIterations = 2,
int keySize = 256) int keySize = 256)
{ {
if (string.IsNullOrEmpty(cipherText)) if (string.IsNullOrEmpty(cipherText))
return ""; return "";
byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector); byte[] initialVectorBytes;
byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt); byte[] saltValueBytes;
byte[] cipherTextBytes = Convert.FromBase64String(cipherText); byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
// Extract metadata from file
AESMetadata metadata = new AESMetadata();
metadata.GetMetadata(cipherTextBytes);
saltValueBytes = metadata.salt;
initialVectorBytes = metadata.initialVector;
metadata.DeleteMetadataFromBuffer(ref cipherTextBytes);
PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes
(password, saltValueBytes, hashAlgorithm, passwordIterations); (password, saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = derivedPassword.GetBytes(keySize / 8); byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged(); RijndaelManaged symmetricKey = new RijndaelManaged();
@ -71,10 +162,10 @@ public static string Decrypt(string cipherText, string password,
byte[] plainTextBytes = new byte[cipherTextBytes.Length]; byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int byteCount = 0; int byteCount = 0;
using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor using (MemoryStream memStream = new MemoryStream(cipherTextBytes))
(keyBytes, initialVectorBytes))
{ {
using (MemoryStream memStream = new MemoryStream(cipherTextBytes)) using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor
(keyBytes, initialVectorBytes))
{ {
using (CryptoStream cryptoStream using (CryptoStream cryptoStream
= new CryptoStream(memStream, decryptor, CryptoStreamMode.Read)) = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
@ -84,9 +175,10 @@ public static string Decrypt(string cipherText, string password,
cryptoStream.Close(); cryptoStream.Close();
} }
} }
symmetricKey.Dispose();
} }
symmetricKey.Clear();
return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount); return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
} }
} }

View file

@ -51,7 +51,7 @@ void SaltMAC()
DialogResult res = new DialogResult(); DialogResult res = new DialogResult();
using (new CenterWinDialog(this)) using (new CenterWinDialog(this))
{ {
res = MessageBox.Show("Get The Salt from mac address? (You can edit it by himself in Settings)", "Crypto Notepad", res = MessageBox.Show("Get The Salt from mac address? (You can change it yourself in Settings)", "Crypto Notepad",
MessageBoxButtons.YesNo, MessageBoxIcon.Question); MessageBoxButtons.YesNo, MessageBoxIcon.Question);
} }
@ -88,7 +88,7 @@ void DecryptAES()
{ {
string opnfile = File.ReadAllText(OpenFile.FileName); string opnfile = File.ReadAllText(OpenFile.FileName);
string NameWithotPath = Path.GetFileName(OpenFile.FileName); string NameWithotPath = Path.GetFileName(OpenFile.FileName);
string de = AES.Decrypt(opnfile, publicVar.encryptionKey, ps.TheSalt, ps.HashAlgorithm, ps.PasswordIterations, "16CHARSLONG12345", ps.KeySize); string de = AES.Decrypt(opnfile, publicVar.encryptionKey, ps.HashAlgorithm, ps.PasswordIterations, ps.KeySize);
customRTB.Text = de; customRTB.Text = de;
this.Text = appName + NameWithotPath; this.Text = appName + NameWithotPath;
@ -165,7 +165,7 @@ private void openAsotiations()
} }
publicVar.okPressed = false; publicVar.okPressed = false;
string de = AES.Decrypt(opnfile, publicVar.encryptionKey, ps.TheSalt, ps.HashAlgorithm, ps.PasswordIterations, "16CHARSLONG12345", ps.KeySize); string de = AES.Decrypt(opnfile, publicVar.encryptionKey, ps.HashAlgorithm, ps.PasswordIterations, ps.KeySize);
customRTB.Text = de; customRTB.Text = de;
this.Text = appName + NameWithotPath; this.Text = appName + NameWithotPath;
@ -234,8 +234,15 @@ private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
filename = SaveFile.FileName; filename = SaveFile.FileName;
// Generate random initialization vector
RandomNumberGenerator RandNumGen = RNGCryptoServiceProvider.Create();
byte[] RandInitVector = new byte[16];
RandNumGen.GetNonZeroBytes(RandInitVector);
string noenc = customRTB.Text; string noenc = customRTB.Text;
string en = AES.Encrypt(customRTB.Text, publicVar.encryptionKey, ps.TheSalt, ps.HashAlgorithm, ps.PasswordIterations, "16CHARSLONG12345", ps.KeySize); string en = AES.Encrypt(customRTB.Text, publicVar.encryptionKey, RandInitVector, ps.TheSalt, ps.HashAlgorithm, ps.PasswordIterations, ps.KeySize);
RandNumGen.Dispose();
customRTB.Text = en; customRTB.Text = en;
StreamWriter sw = new StreamWriter(filename); StreamWriter sw = new StreamWriter(filename);
int i = customRTB.Lines.Count(); int i = customRTB.Lines.Count();
@ -374,8 +381,15 @@ private void saveToolStripMenuItem1_Click_1(object sender, EventArgs e)
publicVar.okPressed = false; publicVar.okPressed = false;
} }
// Generate random initialization vector
RandomNumberGenerator RandNumGen = RNGCryptoServiceProvider.Create();
byte[] RandInitVector = new byte[16];
RandNumGen.GetNonZeroBytes(RandInitVector);
string noenc = customRTB.Text; string noenc = customRTB.Text;
string en = AES.Encrypt(customRTB.Text, publicVar.encryptionKey, ps.TheSalt, ps.HashAlgorithm, ps.PasswordIterations, "16CHARSLONG12345", ps.KeySize); string en = AES.Encrypt(customRTB.Text, publicVar.encryptionKey, RandInitVector, ps.TheSalt, ps.HashAlgorithm, ps.PasswordIterations, ps.KeySize);
RandNumGen.Dispose();
customRTB.Text = en; customRTB.Text = en;
StreamWriter sw = new StreamWriter(filename); StreamWriter sw = new StreamWriter(filename);
int i = customRTB.Lines.Count(); int i = customRTB.Lines.Count();
@ -936,7 +950,7 @@ void AutoLock(bool minimize)
OpenFile.FileName = filename; OpenFile.FileName = filename;
string opnfile = File.ReadAllText(OpenFile.FileName); string opnfile = File.ReadAllText(OpenFile.FileName);
string NameWithotPath = Path.GetFileName(OpenFile.FileName); string NameWithotPath = Path.GetFileName(OpenFile.FileName);
string de = AES.Decrypt(opnfile, publicVar.encryptionKey, ps.TheSalt, ps.HashAlgorithm, ps.PasswordIterations, "16CHARSLONG12345", ps.KeySize); string de = AES.Decrypt(opnfile, publicVar.encryptionKey, ps.HashAlgorithm, ps.PasswordIterations, ps.KeySize);
this.Text = appName + NameWithotPath; this.Text = appName + NameWithotPath;
filename = OpenFile.FileName; filename = OpenFile.FileName;

View file

@ -7,6 +7,8 @@ public partial class Form2 : Form
{ {
public Form2() public Form2()
{ {
// Initialize to false in case user presses the exit button
publicVar.okPressed = false;
InitializeComponent(); InitializeComponent();
} }