mirror of
https://github.com/Crypto-Notepad/Crypto-Notepad.git
synced 2026-03-11 08:55:25 +00:00
Merge pull request #9 from h5p9sl/master
Added file metadata, and randomized initialization vectors.
This commit is contained in:
commit
6f21bb09b3
3 changed files with 132 additions and 24 deletions
|
|
@ -5,17 +5,95 @@
|
|||
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue