/// <summary> /// AES Decryption /// </summary> /// <param name="input"></param> /// <param name="aesKey"></param> /// <param name="aesVI"></param> /// <returns></returns> public string Decrypt(string input, string aesKey, string aesIV) { var rijndaelKey = new RijndaelRequest(aesKey, aesIV); //, 10, 500, 512, "SHA512", null, 1024); return rijndaelEnhancedService.Decrypt(rijndaelKey, input); }
/// <summary> /// Decrypts a base64-encoded cipher text value and generates a byte array /// of plain text data. /// </summary> /// <param name="cipherTextBytes"> /// Byte array containing encrypted data. /// </param> /// <returns> /// Byte array containing decrypted value. /// </returns> public byte[] DecryptToBytes(RijndaelRequest rijndaelRequest, byte[] cipherTextBytes) { byte[] decryptedBytes = null; byte[] plainTextBytes = null; int decryptedByteCount = 0; int saltLen = 0; var memoryStream = new MemoryStream(cipherTextBytes); // Since we do not know how big decrypted value will be, use the same // size as cipher text. Cipher text is always longer than plain text // (in block cipher encryption), so we will just use the number of // decrypted data byte after we know how big it is. decryptedBytes = new byte[cipherTextBytes.Length]; // Let's make cryptographic operations thread-safe. lock (this) { // To perform decryption, we must use the Read mode. var cryptoStream = new CryptoStream( memoryStream, rijndaelRequest.Decryptor, CryptoStreamMode.Read); // Decrypting data and get the count of plain text bytes. decryptedByteCount = cryptoStream.Read(decryptedBytes, 0, decryptedBytes.Length); // Release memory. memoryStream.Close(); cryptoStream.Close(); } // If we are using salt, get its length from the first 4 bytes of plain // text data. if (rijndaelRequest.MaxSaltLength > 0 && rijndaelRequest.MaxSaltLength >= rijndaelRequest.MinSaltLength) { saltLen = (decryptedBytes[0] & 0x03) | (decryptedBytes[1] & 0x0c) | (decryptedBytes[2] & 0x30) | (decryptedBytes[3] & 0xc0); } // Allocate the byte array to hold the original plain text (without salt). plainTextBytes = new byte[decryptedByteCount - saltLen]; // Copy original plain text discarding the salt value if needed. Array.Copy(decryptedBytes, saltLen, plainTextBytes, 0, decryptedByteCount - saltLen); // Return original plain text value. return plainTextBytes; }
/// <summary> /// Decrypts a byte array containing cipher text value and generates a /// string result. /// </summary> /// <param name="cipherTextBytes"> /// Byte array containing encrypted data. /// </param> /// <returns> /// Decrypted string value. /// </returns> public string Decrypt(RijndaelRequest rijndaelRequest, byte[] cipherTextBytes) { return Encoding.UTF8.GetString(DecryptToBytes(rijndaelRequest, cipherTextBytes)); }
/// <summary> /// Decrypts a base64-encoded cipher text value and generates a byte array /// of plain text data. /// </summary> /// <param name="cipherText"> /// Base64-encoded cipher text string to be decrypted. /// </param> /// <returns> /// Byte array containing decrypted value. /// </returns> public byte[] DecryptToBytes(RijndaelRequest rijndaelRequest, string cipherText) { return DecryptToBytes(rijndaelRequest, Convert.FromBase64String(cipherText)); }
/// <summary> /// Generates an array holding cryptographically strong bytes. /// </summary> /// <returns> /// Array of randomly generated bytes. /// </returns> /// <remarks> /// Salt size will be defined at random or exactly as specified by the /// minSlatLen and maxSaltLen parameters passed to the object constructor. /// The first four bytes of the salt array will contain the salt length /// split into four two-bit pieces. /// </remarks> private byte[] GenerateSalt(RijndaelRequest rijndaelRequest) { // We don't have the length, yet. int saltLen = 0; // If min and max salt values are the same, it should not be random. if (rijndaelRequest.MinSaltLength == rijndaelRequest.MaxSaltLength) saltLen = rijndaelRequest.MinSaltLength; // Use random number generator to calculate salt length. else saltLen = GenerateRandomNumber(rijndaelRequest.MinSaltLength, rijndaelRequest.MaxSaltLength); // Allocate byte array to hold our salt. var salt = new byte[saltLen]; // Populate salt with cryptographically strong bytes. var rng = new RNGCryptoServiceProvider(); rng.GetNonZeroBytes(salt); // Split salt length (always one byte) into four two-bit pieces and // store these pieces in the first four bytes of the salt array. salt[0] = (byte)((salt[0] & 0xfc) | (saltLen & 0x03)); salt[1] = (byte)((salt[1] & 0xf3) | (saltLen & 0x0c)); salt[2] = (byte)((salt[2] & 0xcf) | (saltLen & 0x30)); salt[3] = (byte)((salt[3] & 0x3f) | (saltLen & 0xc0)); return salt; }
/// <summary> /// Decrypts a base64-encoded cipher text value generating a string result. /// </summary> /// <param name="cipherText"> /// Base64-encoded cipher text string to be decrypted. /// </param> /// <returns> /// Decrypted string value. /// </returns> public string Decrypt(RijndaelRequest rijndaelRequest, string cipherText) { return Decrypt(rijndaelRequest, Convert.FromBase64String(cipherText)); }
/// <summary> /// Adds an array of randomly generated bytes at the beginning of the /// array holding original plain text value. /// </summary> /// <param name="plainTextBytes"> /// Byte array containing original plain text value. /// </param> /// <returns> /// Either original array of plain text bytes (if salt is not used) or a /// modified array containing a randomly generated salt added at the /// beginning of the plain text bytes. /// </returns> private byte[] AddSalt(RijndaelRequest rijndaelRequest, byte[] plainTextBytes) { // The max salt value of 0 (zero) indicates that we should not use // salt. Also do not use salt if the max salt value is smaller than // the min value. if (rijndaelRequest.MaxSaltLength == 0 || rijndaelRequest.MaxSaltLength < rijndaelRequest.MinSaltLength) return plainTextBytes; // Generate the salt. byte[] saltBytes = GenerateSalt(rijndaelRequest); // Allocate array which will hold salt and plain text bytes. var plainTextBytesWithSalt = new byte[plainTextBytes.Length + saltBytes.Length]; // First, copy salt bytes. Array.Copy(saltBytes, plainTextBytesWithSalt, saltBytes.Length); // Append plain text bytes to the salt value. Array.Copy(plainTextBytes, 0, plainTextBytesWithSalt, saltBytes.Length, plainTextBytes.Length); return plainTextBytesWithSalt; }
/// <summary> /// Encrypts a byte array generating a byte array of cipher text. /// </summary> /// <param name="plainTextBytes"> /// Plain text bytes to be encrypted. /// </param> /// <returns> /// Cipher text formatted as a byte array. /// </returns> public byte[] EncryptToBytes(RijndaelRequest rijndaelRequest, byte[] plainTextBytes) { // Add salt at the beginning of the plain text bytes (if needed). byte[] plainTextBytesWithSalt = AddSalt(rijndaelRequest, plainTextBytes); // Encryption will be performed using memory stream. var memoryStream = new MemoryStream(); // Let's make cryptographic operations thread-safe. lock (this) { // To perform encryption, we must use the Write mode. var cryptoStream = new CryptoStream( memoryStream, rijndaelRequest.Encryptor, CryptoStreamMode.Write); // Start encrypting data. cryptoStream.Write(plainTextBytesWithSalt, 0, plainTextBytesWithSalt.Length); // Finish the encryption operation. cryptoStream.FlushFinalBlock(); // Move encrypted data from memory into a byte array. byte[] cipherTextBytes = memoryStream.ToArray(); // Close memory streams. memoryStream.Close(); cryptoStream.Close(); // Return encrypted data. return cipherTextBytes; } }
/// <summary> /// Encrypts a string value generating a byte array of cipher text. /// </summary> /// <param name="plainText"> /// Plain text string to be encrypted. /// </param> /// <returns> /// Cipher text formatted as a byte array. /// </returns> public byte[] EncryptToBytes(RijndaelRequest rijndaelRequest, string plainText) { return EncryptToBytes(rijndaelRequest, Encoding.UTF8.GetBytes(plainText)); }
/// <summary> /// Encrypts a byte array generating a base64-encoded string. /// </summary> /// <param name="plainTextBytes"> /// Plain text bytes to be encrypted. /// </param> /// <returns> /// Cipher text formatted as a base64-encoded string. /// </returns> public string Encrypt(RijndaelRequest rijndaelRequest, byte[] plainTextBytes) { return Convert.ToBase64String(EncryptToBytes(rijndaelRequest, plainTextBytes)); }
/// <summary> /// Encrypts a string value generating a base64-encoded string. /// </summary> /// <param name="plainText"> /// Plain text string to be encrypted. /// </param> /// <returns> /// Cipher text formatted as a base64-encoded string. /// </returns> public string Encrypt(RijndaelRequest rijndaelRequest, string plainText) { return Encrypt(rijndaelRequest, Encoding.UTF8.GetBytes(plainText)); }