Encrypting a text is not enough, its integrity must also be secured. The easiest way to do this is to add a checksum to the original before encryption (and remove it again after successful decryption).
If the checksum calculated after decryption does not match the decrypted one, the password is incorrect.
Very Simple ;-)
I wrote this small class "SimpleCrypt" (or call it "Crypto-Safe" ;-) ) for my own project, but I think it could be helpful for many others too.
Usage
- The user password is set by the constructor
- Encryption works with any string (length >= 0 ). The result is an AES encrypted string in Base64 format, that is sealed with an MD5 hash (128 bit).
- Decryption checks Base64 format and integrity of the hash.
Here is some Test data
Used Password is "PASSWORD":
Example
The string ABC is encrypted to h6EHx1dEYy/cjNZJihvkgGslpwi0gTNGtM5lt0j2Jxc=
Have fun.
The encryption
/* The Input String (UTF8) is sealed with a MD5-128-Bit-Hash and then Crypted to a Base64 String */
public string EncryptToBase64(string originalText)
{
var userBytes = Encoding.UTF8.GetBytes(originalText); // UTF8 saves Space
var userHash = MD5.Create().ComputeHash(userBytes);
SymmetricAlgorithm crypt = Aes.Create(); // (Default: AES-CCM (Counter with CBC-MAC))
crypt.Key = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Password)); // MD5: 128 Bit Hash
crypt.IV = new byte[16]; // by Default. IV[] to 0.. is OK simple crypt
using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, crypt.CreateEncryptor(), CryptoStreamMode.Write);
cryptoStream.Write(userBytes, 0, userBytes.Length); // User Data
cryptoStream.Write(userHash, 0, userHash.Length); // Add HASH
cryptoStream.FlushFinalBlock();
var resultString = Convert.ToBase64String(memoryStream.ToArray());
return resultString;
}
Decryption
/* Try to get original (decrypted) String. Password (and Base64-format) must be correct */
public string DecryptFromBase64(string encryptedText)
{
var encryptedBytes = Convert.FromBase64String(encryptedText);
SymmetricAlgorithm crypt = Aes.Create();
crypt.Key = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Password));
crypt.IV = new byte[16];
using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, crypt.CreateDecryptor(), CryptoStreamMode.Write);
cryptoStream.Write(encryptedBytes, 0, encryptedBytes.Length);
cryptoStream.FlushFinalBlock();
var allBytes = memoryStream.ToArray();
var userLen = allBytes.Length - 16;
if (userLen < 0) throw new Exception("Invalid Len"); // No Hash?
var userHash = new byte[16];
Array.Copy(allBytes, userLen, userHash, 0, 16); // Get the 2 Hashes
var decryptHash = MD5.Create().ComputeHash(allBytes, 0, userLen);
if (userHash.SequenceEqual(decryptHash) == false) throw new Exception("Invalid Hash");
var resultString = Encoding.UTF8.GetString(allBytes,0, userLen);
return resultString;
}
Output