diff --git a/Crypto Notepad/AES.cs b/Crypto Notepad/AES.cs
index 53d3fc9..b9e191a 100644
--- a/Crypto Notepad/AES.cs
+++ b/Crypto Notepad/AES.cs
@@ -5,17 +5,95 @@
namespace Crypto_Notepad
{
+ ///
+ /// This class extracts information needed for decryption from a .cnp file
+ ///
+ class AESMetadata
+ {
+ ///
+ /// Offset to actual AES data; size of metadata
+ ///
+ 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
{
- public static string Encrypt(string plainText, string password,
+ public static string Encrypt(string plainText, string password, byte[] initialVectorBytes,
string salt = "Kosher", string hashAlgorithm = "SHA1",
- int passwordIterations = 2, string initialVector = "OFRna73m*aze01xY",
- int keySize = 256)
+ int passwordIterations = 2, int keySize = 256)
{
if (string.IsNullOrEmpty(plainText))
return "";
- byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
@@ -28,10 +106,16 @@ public static string Encrypt(string plainText, string password,
byte[] cipherTextBytes = null;
- using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor
- (keyBytes, initialVectorBytes))
+ using (MemoryStream memStream = new MemoryStream())
{
- 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
(memStream, encryptor, CryptoStreamMode.Write))
@@ -45,24 +129,31 @@ public static string Encrypt(string plainText, string password,
}
}
- symmetricKey.Clear();
+ symmetricKey.Dispose();
return Convert.ToBase64String(cipherTextBytes);
}
public static string Decrypt(string cipherText, string password,
- string salt = "Kosher", string hashAlgorithm = "SHA1",
- int passwordIterations = 2, string initialVector = "OFRna73m*aze01xY",
+ string hashAlgorithm = "SHA1",
+ int passwordIterations = 2,
int keySize = 256)
{
if (string.IsNullOrEmpty(cipherText))
return "";
- byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
- byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
+ byte[] initialVectorBytes;
+ byte[] saltValueBytes;
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
- (password, saltValueBytes, hashAlgorithm, passwordIterations);
+ (password, saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
@@ -71,10 +162,10 @@ public static string Decrypt(string cipherText, string password,
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int byteCount = 0;
- using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor
- (keyBytes, initialVectorBytes))
+ using (MemoryStream memStream = new MemoryStream(cipherTextBytes))
{
- using (MemoryStream memStream = new MemoryStream(cipherTextBytes))
+ using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor
+ (keyBytes, initialVectorBytes))
{
using (CryptoStream cryptoStream
= new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
@@ -84,9 +175,10 @@ public static string Decrypt(string cipherText, string password,
cryptoStream.Close();
}
}
- }
- symmetricKey.Clear();
+ symmetricKey.Dispose();
+ }
+
return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
}
}
diff --git a/Crypto Notepad/Form1.cs b/Crypto Notepad/Form1.cs
index d7bb490..00cd740 100644
--- a/Crypto Notepad/Form1.cs
+++ b/Crypto Notepad/Form1.cs
@@ -51,7 +51,7 @@ void SaltMAC()
DialogResult res = new DialogResult();
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);
}
@@ -88,7 +88,7 @@ void DecryptAES()
{
string opnfile = File.ReadAllText(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;
this.Text = appName + NameWithotPath;
@@ -165,7 +165,7 @@ private void openAsotiations()
}
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;
this.Text = appName + NameWithotPath;
@@ -234,8 +234,15 @@ private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
filename = SaveFile.FileName;
+ // Generate random initialization vector
+ RandomNumberGenerator RandNumGen = RNGCryptoServiceProvider.Create();
+ byte[] RandInitVector = new byte[16];
+ RandNumGen.GetNonZeroBytes(RandInitVector);
+
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;
StreamWriter sw = new StreamWriter(filename);
int i = customRTB.Lines.Count();
@@ -374,8 +381,15 @@ private void saveToolStripMenuItem1_Click_1(object sender, EventArgs e)
publicVar.okPressed = false;
}
+ // Generate random initialization vector
+ RandomNumberGenerator RandNumGen = RNGCryptoServiceProvider.Create();
+ byte[] RandInitVector = new byte[16];
+ RandNumGen.GetNonZeroBytes(RandInitVector);
+
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;
StreamWriter sw = new StreamWriter(filename);
int i = customRTB.Lines.Count();
@@ -936,7 +950,7 @@ void AutoLock(bool minimize)
OpenFile.FileName = filename;
string opnfile = File.ReadAllText(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;
filename = OpenFile.FileName;
diff --git a/Crypto Notepad/Form2.cs b/Crypto Notepad/Form2.cs
index 872b9d4..8b1bfaa 100644
--- a/Crypto Notepad/Form2.cs
+++ b/Crypto Notepad/Form2.cs
@@ -7,6 +7,8 @@ public partial class Form2 : Form
{
public Form2()
{
+ // Initialize to false in case user presses the exit button
+ publicVar.okPressed = false;
InitializeComponent();
}