/// <summary> /// Validates that specified Key and Vector are appropriate to the Algorithm to be used for the encryption /// </summary> /// <param name="Provider"></param> /// <param name="Data"></param> /// <param name="Key"></param> /// <param name="Vector"></param> /// <param name="Mode"></param> /// <returns></returns> private bool ValidateSymmetricalEncryptionParameters(System.Security.Cryptography.SymmetricAlgorithm Provider,ref byte[] Data, ref byte[] Key, ref byte[] Vector, eCryptoMode Mode) { // DATA VALIDATION // =============== if (Data.Length == 0) { switch (Mode) { case eCryptoMode.Encrypt: { throw new SymmetricEncryptionDataValidationException("No data to encrypt"); break; } case eCryptoMode.Decrypt: { throw new SymmetricEncryptionDataValidationException("No data to decrypt"); break; } } } // KEY VALIDATION // ============== if (Key.Length == 0) { // Supply a key if one has not been supplied. if (Mode == eCryptoMode.Encrypt) { Key = System.Text.ASCIIEncoding.ASCII.GetBytes(this.GetSymmetricKey(Provider)); } } else { // Pad the key if it is too short/trim the key if it is too long while (Key.Length * 8 != Provider.KeySize) { if (Key.Length * 8 < Provider.KeySize) { // TODO // ReDim Preserve Key(Key.Length); Key[Key.Length - 1] = 0; } else { // TODO //ReDim Preserve Key(Key.Length - 2); } } } // Ensure that the key is strong - validation will error if a weak key is used. // Can only be checked for DES and TripleDES Keys if (Provider.GetType() == typeof(DESCryptoServiceProvider)) { if ( DESCryptoServiceProvider.IsWeakKey(Key)) { throw new SymmetricEncryptionDataValidationException("Known weak key supplied for DES algorithm."); } } if (Provider.GetType() == typeof(TripleDESCryptoServiceProvider)) { if ( TripleDESCryptoServiceProvider.IsWeakKey(Key)) { throw new SymmetricEncryptionDataValidationException("Known weak key supplied for TripleDES algorithm."); } } // VECTOR VALIDATION // ================= if (Vector.Length == 0) { if (Mode == eCryptoMode.Encrypt) { Vector = System.Text.ASCIIEncoding.ASCII.GetBytes(this.GetSymmetricVector(Provider)); } } // Assume validation will be passed if no errors are detected return true; }
/// <summary> /// Performs Encryption\Decryption using specified Algorithm, Key, and Vector /// </summary> /// <param name="cryptoAlgorithm"></param> /// <param name="cryptoMode"></param> /// <param name="inputData"></param> /// <param name="encryptionKey"></param> /// <param name="encryptionVector"></param> /// <returns></returns> private byte[] SymmetricCrypto(eSymmetricCryptoAlgorithm cryptoAlgorithm, eCryptoMode cryptoMode, byte[] inputData, byte[] encryptionKey, byte[] encryptionVector) { SymmetricAlgorithm cryptProvider; ICryptoTransform cryptEngine = null; MemoryStream objCryptoStream; CryptoStream objCryptoProcess; byte[] arrOutputData; // Create encryption provider - required for validation steps below // ---------------------------------------------------------------- cryptProvider = GetSymmetricEncryptionProvider(cryptoAlgorithm); // Validate contents of byte arrays // -------------------------------- if (ValidateSymmetricalEncryptionParameters(cryptProvider, ref inputData, ref encryptionKey, ref encryptionVector, cryptoMode) == false) { return null; } // Attach Key and Vector to cryptProvider cryptProvider.Key = encryptionKey; cryptProvider.IV = encryptionVector; // Encrypt\Decrypt objCryptoStream = new MemoryStream(); switch (cryptoMode) { case eCryptoMode.Encrypt: { cryptEngine = cryptProvider.CreateEncryptor(); break; } case eCryptoMode.Decrypt: { cryptEngine = cryptProvider.CreateDecryptor(); break; } } // Encrypted\Decrypt value into a Stream objCryptoProcess = new CryptoStream(objCryptoStream, cryptEngine, CryptoStreamMode.Write); objCryptoProcess.Write(inputData, 0, inputData.Length); objCryptoProcess.Close(); // Extract Encrypted\Decrypted value from Stream arrOutputData = objCryptoStream.ToArray(); cryptEngine = null; cryptProvider = null; objCryptoStream = null; objCryptoProcess = null; return arrOutputData; }