texto llave encriptar desencriptar datos con cadena c# .net encryption mono cryptography

llave - ¿Cifrar y descifrar una cadena en C#?



encriptar y desencriptar en c++ (25)

Aquí hay un ejemplo usando RSA.

Importante: existe un límite para el tamaño de los datos que puede cifrar con el cifrado RSA, KeySize - MinimumPadding . por ejemplo, 256 bytes (suponiendo una clave de 2048 bits) - 42 bytes (mínimo relleno OEAP) = 214 bytes (tamaño máximo de texto plano)

Reemplace your_rsa_key con su clave RSA.

var provider = new System.Security.Cryptography.RSACryptoServiceProvider(); provider.ImportParameters(your_rsa_key); var encryptedBytes = provider.Encrypt( System.Text.Encoding.UTF8.GetBytes("Hello World!"), true); string decryptedTest = System.Text.Encoding.UTF8.GetString( provider.Decrypt(encryptedBytes, true));

Para obtener más información, visite MSDN - RSACryptoServiceProvider

¿Cómo puedo cifrar y descifrar una cadena en C #?


BouncyCastle es una excelente biblioteca Crypto para .NET, está disponible como un paquete Nuget para instalar en tus proyectos. Me gusta mucho más que lo que está disponible actualmente en la biblioteca System.Security.Cryptography. Le ofrece muchas más opciones en términos de algoritmos disponibles y proporciona más modos para esos algoritmos.

Este es un ejemplo de una implementación de TwoFish , que fue escrita por Bruce Schneier (el héroe de todos los paranoicos de allí). Es un algoritmo simétrico como el Rijndael (también conocido como AES). Fue uno de los tres finalistas para el estándar AES y hermano de otro famoso algoritmo escrito por Bruce Schneier llamado BlowFish.

Lo primero con bouncycastle es crear una clase de encriptador, esto facilitará la implementación de otros cifrados de bloque dentro de la biblioteca. La siguiente clase de encriptador toma un argumento genérico T donde T implementa IBlockCipher y tiene un constructor predeterminado.

ACTUALIZACIÓN: debido a la demanda popular, he decidido implementar la generación de un IV al azar, así como incluir un HMAC en esta clase. Aunque desde una perspectiva de estilo, esto va en contra del principio SOLID de responsabilidad única, debido a la naturaleza de lo que esta clase hace, renigí. Esta clase ahora tomará dos parámetros genéricos, uno para el cifrado y otro para el resumen. Genera automáticamente la IV utilizando RNGCryptoServiceProvider para proporcionar una buena entropía de RNG, y le permite usar el algoritmo de resumen que desee de BouncyCastle para generar el MAC.

using System; using System.Security.Cryptography; using System.Text; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Macs; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Paddings; using Org.BouncyCastle.Crypto.Parameters; public sealed class Encryptor<TBlockCipher, TDigest> where TBlockCipher : IBlockCipher, new() where TDigest : IDigest, new() { private Encoding encoding; private IBlockCipher blockCipher; private BufferedBlockCipher cipher; private HMac mac; private byte[] key; public Encryptor(Encoding encoding, byte[] key, byte[] macKey) { this.encoding = encoding; this.key = key; this.Init(key, macKey, new Pkcs7Padding()); } public Encryptor(Encoding encoding, byte[] key, byte[] macKey, IBlockCipherPadding padding) { this.encoding = encoding; this.key = key; this.Init(key, macKey, padding); } private void Init(byte[] key, byte[] macKey, IBlockCipherPadding padding) { this.blockCipher = new CbcBlockCipher(new TBlockCipher()); this.cipher = new PaddedBufferedBlockCipher(this.blockCipher, padding); this.mac = new HMac(new TDigest()); this.mac.Init(new KeyParameter(macKey)); } public string Encrypt(string plain) { return Convert.ToBase64String(EncryptBytes(plain)); } public byte[] EncryptBytes(string plain) { byte[] input = this.encoding.GetBytes(plain); var iv = this.GenerateIV(); var cipher = this.BouncyCastleCrypto(true, input, new ParametersWithIV(new KeyParameter(key), iv)); byte[] message = CombineArrays(iv, cipher); this.mac.Reset(); this.mac.BlockUpdate(message, 0, message.Length); byte[] digest = new byte[this.mac.GetUnderlyingDigest().GetDigestSize()]; this.mac.DoFinal(digest, 0); var result = CombineArrays(digest, message); return result; } public byte[] DecryptBytes(byte[] bytes) { // split the digest into component parts var digest = new byte[this.mac.GetUnderlyingDigest().GetDigestSize()]; var message = new byte[bytes.Length - digest.Length]; var iv = new byte[this.blockCipher.GetBlockSize()]; var cipher = new byte[message.Length - iv.Length]; Buffer.BlockCopy(bytes, 0, digest, 0, digest.Length); Buffer.BlockCopy(bytes, digest.Length, message, 0, message.Length); if (!IsValidHMac(digest, message)) { throw new CryptoException(); } Buffer.BlockCopy(message, 0, iv, 0, iv.Length); Buffer.BlockCopy(message, iv.Length, cipher, 0, cipher.Length); byte[] result = this.BouncyCastleCrypto(false, cipher, new ParametersWithIV(new KeyParameter(key), iv)); return result; } public string Decrypt(byte[] bytes) { return this.encoding.GetString(DecryptBytes(bytes)); } public string Decrypt(string cipher) { return this.Decrypt(Convert.FromBase64String(cipher)); } private bool IsValidHMac(byte[] digest, byte[] message) { this.mac.Reset(); this.mac.BlockUpdate(message, 0, message.Length); byte[] computed = new byte[this.mac.GetUnderlyingDigest().GetDigestSize()]; this.mac.DoFinal(computed, 0); return AreEqual(digest,computed); } private static bool AreEqual(byte [] digest, byte[] computed) { if(digest.Length != computed.Length) { return false; } int result = 0; for (int i = 0; i < digest.Length; i++) { // compute equality of all bytes before returning. // helps prevent timing attacks: // https://codahale.com/a-lesson-in-timing-attacks/ result |= digest[i] ^ computed[i]; } return result == 0; } private byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, ICipherParameters parameters) { try { cipher.Init(forEncrypt, parameters); return this.cipher.DoFinal(input); } catch (CryptoException) { throw; } } private byte[] GenerateIV() { using (var provider = new RNGCryptoServiceProvider()) { // 1st block byte[] result = new byte[this.blockCipher.GetBlockSize()]; provider.GetBytes(result); return result; } } private static byte[] CombineArrays(byte[] source1, byte[] source2) { byte[] result = new byte[source1.Length + source2.Length]; Buffer.BlockCopy(source1, 0, result, 0, source1.Length); Buffer.BlockCopy(source2, 0, result, source1.Length, source2.Length); return result; } }

A continuación, simplemente llame a los métodos de cifrar y descifrar en la nueva clase, aquí está el ejemplo usando twofish:

var encrypt = new Encryptor<TwofishEngine, Sha1Digest>(Encoding.UTF8, key, hmacKey); string cipher = encrypt.Encrypt("TEST"); string plainText = encrypt.Decrypt(cipher);

Es tan fácil sustituir otro cifrado de bloque como TripleDES:

var des = new Encryptor<DesEdeEngine, Sha1Digest>(Encoding.UTF8, key, hmacKey); string cipher = des.Encrypt("TEST"); string plainText = des.Decrypt(cipher);

Finalmente, si desea usar AES con SHA256 HMAC, puede hacer lo siguiente:

var aes = new Encryptor<AesEngine, Sha256Digest>(Encoding.UTF8, key, hmacKey); cipher = aes.Encrypt("TEST"); plainText = aes.Decrypt(cipher);

La parte más difícil del cifrado en realidad trata con las claves y no con los algoritmos. Tendrá que pensar en dónde guarda sus llaves y, si tiene que hacerlo, cómo las intercambiará. Todos estos algoritmos han resistido la prueba del tiempo y son extremadamente difíciles de romper. Alguien que quiera robarte información no pasará la eternidad haciendo el criptoanálisis de tus mensajes, intentará averiguar en qué lugar o dónde está tu clave. Entonces, # 1 elija sus claves con prudencia, # 2 guárdelas en un lugar seguro, si utiliza un web.config e IIS, puede encriptar partes del web.config , y finalmente si tiene que intercambiar las claves, asegúrese de El protocolo para intercambiar la clave es seguro.

Actualización 2 Se cambió el método de comparación para mitigar los ataques de tiempo. Ver más información aquí http://codahale.com/a-lesson-in-timing-attacks/ . También se actualizó de forma predeterminada al relleno PKCS7 y se agregó un nuevo constructor para permitir al usuario final la posibilidad de elegir qué relleno le gustaría usar. Gracias a @CodesInChaos por las sugerencias.


A continuación se muestra cómo se puede realizar el cifrado / descifrado AES-GCM utilizando el paquete Bouncy Castle.

Encontré esa muestra cuando se buscó en Google para descifrar datos de la crypto/aesAPI de GOlang :

const ( gcmBlockSize = 16 // this is key size gcmTagSize = 16 // this is mac gcmStandardNonceSize = 12 // this is nonce ) func encrypt(data []byte, passphrase string) []byte { block, _ := aes.NewCipher([]byte(createHash(passphrase))) gcm, err := cipher.NewGCM(block) if err != nil { panic(err.Error()) } nonce := make([]byte, gcm.NonceSize()) if _, err = io.ReadFull(rand.Reader, nonce); err != nil { panic(err.Error()) } ciphertext := gcm.Seal(nonce, nonce, data, nil) return ciphertext }

.Net muestra funciona como un encanto con clave (256 bits), mac (128 bits) y nonce (96 bits).


EDITAR 2013-octubre : aunque he editado esta respuesta a lo largo del tiempo para solucionar las deficiencias, consulte la respuesta de jbtule para obtener una solución más sólida e informada.

https://.com/a/10366194/188474

Respuesta original:

Este es un ejemplo práctico derivado de la documentación de "Clase RijndaelManaged" y el Kit de capacitación de MCTS .

EDITAR 2012-abril : esta respuesta se editó antes de la sugerencia de IV por jbtule y como se ilustra aquí:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged%28v=vs.95%29.aspx

¡Buena suerte!

public class Crypto { //While an app specific salt is not the best practice for //password based encryption, it''s probably safe enough as long as //it is truly uncommon. Also too much work to alter this answer otherwise. private static byte[] _salt = __To_Do__("Add a app specific salt here"); /// <summary> /// Encrypt the given string using AES. The string can be decrypted using /// DecryptStringAES(). The sharedSecret parameters must match. /// </summary> /// <param name="plainText">The text to encrypt.</param> /// <param name="sharedSecret">A password used to generate a key for encryption.</param> public static string EncryptStringAES(string plainText, string sharedSecret) { if (string.IsNullOrEmpty(plainText)) throw new ArgumentNullException("plainText"); if (string.IsNullOrEmpty(sharedSecret)) throw new ArgumentNullException("sharedSecret"); string outStr = null; // Encrypted string to return RijndaelManaged aesAlg = null; // RijndaelManaged object used to encrypt the data. try { // generate the key from the shared secret and the salt Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt); // Create a RijndaelManaged object aesAlg = new RijndaelManaged(); aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); // Create a decryptor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { // prepend the IV msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int)); msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length); using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); } } outStr = Convert.ToBase64String(msEncrypt.ToArray()); } } finally { // Clear the RijndaelManaged object. if (aesAlg != null) aesAlg.Clear(); } // Return the encrypted bytes from the memory stream. return outStr; } /// <summary> /// Decrypt the given string. Assumes the string was encrypted using /// EncryptStringAES(), using an identical sharedSecret. /// </summary> /// <param name="cipherText">The text to decrypt.</param> /// <param name="sharedSecret">A password used to generate a key for decryption.</param> public static string DecryptStringAES(string cipherText, string sharedSecret) { if (string.IsNullOrEmpty(cipherText)) throw new ArgumentNullException("cipherText"); if (string.IsNullOrEmpty(sharedSecret)) throw new ArgumentNullException("sharedSecret"); // Declare the RijndaelManaged object // used to decrypt the data. RijndaelManaged aesAlg = null; // Declare the string used to hold // the decrypted text. string plaintext = null; try { // generate the key from the shared secret and the salt Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt); // Create the streams used for decryption. byte[] bytes = Convert.FromBase64String(cipherText); using (MemoryStream msDecrypt = new MemoryStream(bytes)) { // Create a RijndaelManaged object // with the specified key and IV. aesAlg = new RijndaelManaged(); aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); // Get the initialization vector from the encrypted stream aesAlg.IV = ReadByteArray(msDecrypt); // Create a decrytor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) // Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } finally { // Clear the RijndaelManaged object. if (aesAlg != null) aesAlg.Clear(); } return plaintext; } private static byte[] ReadByteArray(Stream s) { byte[] rawLength = new byte[sizeof(int)]; if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length) { throw new SystemException("Stream did not contain properly formatted byte array"); } byte[] buffer = new byte[BitConverter.ToInt32(rawLength, 0)]; if (s.Read(buffer, 0, buffer.Length) != buffer.Length) { throw new SystemException("Did not read byte array properly"); } return buffer; } }


Ejemplos modernos de cifrado autenticado simétrico de una cadena.

La mejor práctica general para el cifrado simétrico es utilizar el cifrado autenticado con datos asociados (AEAD), sin embargo, esto no forma parte de las bibliotecas criptográficas .net estándar. Así que el primer ejemplo utiliza AES256 y luego HMAC256 , un cifrado de dos pasos y luego MAC , que requiere más sobrecarga y más claves.

El segundo ejemplo utiliza la práctica más sencilla de AES256- GCM utilizando el código abierto Bouncy Castle (a través de nuget).

Ambos ejemplos tienen una función principal que toma la cadena de mensajes secretos, las claves y una carga útil no secreta opcional y devuelve una cadena cifrada autenticada opcionalmente con los datos no secretos. Lo ideal sería utilizarlos con claves de 256 bits generadas al azar, ver NewKey() .

Ambos ejemplos también tienen métodos de ayuda que utilizan una contraseña de cadena para generar las claves. Estos métodos de ayuda se proporcionan como una conveniencia para coincidir con otros ejemplos, sin embargo, son mucho menos seguros porque la fortaleza de la contraseña será mucho más débil que una clave de 256 bits .

Actualización: Se agregaron las sobrecargas de byte[] , y solo el Gist tiene el formato completo con 4 espacios de sangría y api docs debido a los límites de respuesta de .

.NET incorporado cifrado (AES) -Entonces-MAC (HMAC) [Gist]

/* * This work (Modern Encryption of a String C#, by James Tuley), * identified by James Tuley, is free of known copyright restrictions. * https://gist.github.com/4336842 * http://creativecommons.org/publicdomain/mark/1.0/ */ using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Encryption { public static class AESThenHMAC { private static readonly RandomNumberGenerator Random = RandomNumberGenerator.Create(); //Preconfigured Encryption Parameters public static readonly int BlockBitSize = 128; public static readonly int KeyBitSize = 256; //Preconfigured Password Key Derivation Parameters public static readonly int SaltBitSize = 64; public static readonly int Iterations = 10000; public static readonly int MinPasswordLength = 12; /// <summary> /// Helper that generates a random key on each call. /// </summary> /// <returns></returns> public static byte[] NewKey() { var key = new byte[KeyBitSize / 8]; Random.GetBytes(key); return key; } /// <summary> /// Simple Encryption (AES) then Authentication (HMAC) for a UTF8 Message. /// </summary> /// <param name="secretMessage">The secret message.</param> /// <param name="cryptKey">The crypt key.</param> /// <param name="authKey">The auth key.</param> /// <param name="nonSecretPayload">(Optional) Non-Secret Payload.</param> /// <returns> /// Encrypted Message /// </returns> /// <exception cref="System.ArgumentException">Secret Message Required!;secretMessage</exception> /// <remarks> /// Adds overhead of (Optional-Payload + BlockSize(16) + Message-Padded-To-Blocksize + HMac-Tag(32)) * 1.33 Base64 /// </remarks> public static string SimpleEncrypt(string secretMessage, byte[] cryptKey, byte[] authKey, byte[] nonSecretPayload = null) { if (string.IsNullOrEmpty(secretMessage)) throw new ArgumentException("Secret Message Required!", "secretMessage"); var plainText = Encoding.UTF8.GetBytes(secretMessage); var cipherText = SimpleEncrypt(plainText, cryptKey, authKey, nonSecretPayload); return Convert.ToBase64String(cipherText); } /// <summary> /// Simple Authentication (HMAC) then Decryption (AES) for a secrets UTF8 Message. /// </summary> /// <param name="encryptedMessage">The encrypted message.</param> /// <param name="cryptKey">The crypt key.</param> /// <param name="authKey">The auth key.</param> /// <param name="nonSecretPayloadLength">Length of the non secret payload.</param> /// <returns> /// Decrypted Message /// </returns> /// <exception cref="System.ArgumentException">Encrypted Message Required!;encryptedMessage</exception> public static string SimpleDecrypt(string encryptedMessage, byte[] cryptKey, byte[] authKey, int nonSecretPayloadLength = 0) { if (string.IsNullOrWhiteSpace(encryptedMessage)) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); var cipherText = Convert.FromBase64String(encryptedMessage); var plainText = SimpleDecrypt(cipherText, cryptKey, authKey, nonSecretPayloadLength); return plainText == null ? null : Encoding.UTF8.GetString(plainText); } /// <summary> /// Simple Encryption (AES) then Authentication (HMAC) of a UTF8 message /// using Keys derived from a Password (PBKDF2). /// </summary> /// <param name="secretMessage">The secret message.</param> /// <param name="password">The password.</param> /// <param name="nonSecretPayload">The non secret payload.</param> /// <returns> /// Encrypted Message /// </returns> /// <exception cref="System.ArgumentException">password</exception> /// <remarks> /// Significantly less secure than using random binary keys. /// Adds additional non secret payload for key generation parameters. /// </remarks> public static string SimpleEncryptWithPassword(string secretMessage, string password, byte[] nonSecretPayload = null) { if (string.IsNullOrEmpty(secretMessage)) throw new ArgumentException("Secret Message Required!", "secretMessage"); var plainText = Encoding.UTF8.GetBytes(secretMessage); var cipherText = SimpleEncryptWithPassword(plainText, password, nonSecretPayload); return Convert.ToBase64String(cipherText); } /// <summary> /// Simple Authentication (HMAC) and then Descryption (AES) of a UTF8 Message /// using keys derived from a password (PBKDF2). /// </summary> /// <param name="encryptedMessage">The encrypted message.</param> /// <param name="password">The password.</param> /// <param name="nonSecretPayloadLength">Length of the non secret payload.</param> /// <returns> /// Decrypted Message /// </returns> /// <exception cref="System.ArgumentException">Encrypted Message Required!;encryptedMessage</exception> /// <remarks> /// Significantly less secure than using random binary keys. /// </remarks> public static string SimpleDecryptWithPassword(string encryptedMessage, string password, int nonSecretPayloadLength = 0) { if (string.IsNullOrWhiteSpace(encryptedMessage)) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); var cipherText = Convert.FromBase64String(encryptedMessage); var plainText = SimpleDecryptWithPassword(cipherText, password, nonSecretPayloadLength); return plainText == null ? null : Encoding.UTF8.GetString(plainText); } public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] cryptKey, byte[] authKey, byte[] nonSecretPayload = null) { //User Error Checks if (cryptKey == null || cryptKey.Length != KeyBitSize / 8) throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "cryptKey"); if (authKey == null || authKey.Length != KeyBitSize / 8) throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "authKey"); if (secretMessage == null || secretMessage.Length < 1) throw new ArgumentException("Secret Message Required!", "secretMessage"); //non-secret payload optional nonSecretPayload = nonSecretPayload ?? new byte[] { }; byte[] cipherText; byte[] iv; using (var aes = new AesManaged { KeySize = KeyBitSize, BlockSize = BlockBitSize, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }) { //Use random IV aes.GenerateIV(); iv = aes.IV; using (var encrypter = aes.CreateEncryptor(cryptKey, iv)) using (var cipherStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write)) using (var binaryWriter = new BinaryWriter(cryptoStream)) { //Encrypt Data binaryWriter.Write(secretMessage); } cipherText = cipherStream.ToArray(); } } //Assemble encrypted message and add authentication using (var hmac = new HMACSHA256(authKey)) using (var encryptedStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(encryptedStream)) { //Prepend non-secret payload if any binaryWriter.Write(nonSecretPayload); //Prepend IV binaryWriter.Write(iv); //Write Ciphertext binaryWriter.Write(cipherText); binaryWriter.Flush(); //Authenticate all data var tag = hmac.ComputeHash(encryptedStream.ToArray()); //Postpend tag binaryWriter.Write(tag); } return encryptedStream.ToArray(); } } public static byte[] SimpleDecrypt(byte[] encryptedMessage, byte[] cryptKey, byte[] authKey, int nonSecretPayloadLength = 0) { //Basic Usage Error Checks if (cryptKey == null || cryptKey.Length != KeyBitSize / 8) throw new ArgumentException(String.Format("CryptKey needs to be {0} bit!", KeyBitSize), "cryptKey"); if (authKey == null || authKey.Length != KeyBitSize / 8) throw new ArgumentException(String.Format("AuthKey needs to be {0} bit!", KeyBitSize), "authKey"); if (encryptedMessage == null || encryptedMessage.Length == 0) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); using (var hmac = new HMACSHA256(authKey)) { var sentTag = new byte[hmac.HashSize / 8]; //Calculate Tag var calcTag = hmac.ComputeHash(encryptedMessage, 0, encryptedMessage.Length - sentTag.Length); var ivLength = (BlockBitSize / 8); //if message length is to small just return null if (encryptedMessage.Length < sentTag.Length + nonSecretPayloadLength + ivLength) return null; //Grab Sent Tag Array.Copy(encryptedMessage, encryptedMessage.Length - sentTag.Length, sentTag, 0, sentTag.Length); //Compare Tag with constant time comparison var compare = 0; for (var i = 0; i < sentTag.Length; i++) compare |= sentTag[i] ^ calcTag[i]; //if message doesn''t authenticate return null if (compare != 0) return null; using (var aes = new AesManaged { KeySize = KeyBitSize, BlockSize = BlockBitSize, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }) { //Grab IV from message var iv = new byte[ivLength]; Array.Copy(encryptedMessage, nonSecretPayloadLength, iv, 0, iv.Length); using (var decrypter = aes.CreateDecryptor(cryptKey, iv)) using (var plainTextStream = new MemoryStream()) { using (var decrypterStream = new CryptoStream(plainTextStream, decrypter, CryptoStreamMode.Write)) using (var binaryWriter = new BinaryWriter(decrypterStream)) { //Decrypt Cipher Text from Message binaryWriter.Write( encryptedMessage, nonSecretPayloadLength + iv.Length, encryptedMessage.Length - nonSecretPayloadLength - iv.Length - sentTag.Length ); } //Return Plain Text return plainTextStream.ToArray(); } } } } public static byte[] SimpleEncryptWithPassword(byte[] secretMessage, string password, byte[] nonSecretPayload = null) { nonSecretPayload = nonSecretPayload ?? new byte[] {}; //User Error Checks if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength) throw new ArgumentException(String.Format("Must have a password of at least {0} characters!", MinPasswordLength), "password"); if (secretMessage == null || secretMessage.Length ==0) throw new ArgumentException("Secret Message Required!", "secretMessage"); var payload = new byte[((SaltBitSize / 8) * 2) + nonSecretPayload.Length]; Array.Copy(nonSecretPayload, payload, nonSecretPayload.Length); int payloadIndex = nonSecretPayload.Length; byte[] cryptKey; byte[] authKey; //Use Random Salt to prevent pre-generated weak password attacks. using (var generator = new Rfc2898DeriveBytes(password, SaltBitSize / 8, Iterations)) { var salt = generator.Salt; //Generate Keys cryptKey = generator.GetBytes(KeyBitSize / 8); //Create Non Secret Payload Array.Copy(salt, 0, payload, payloadIndex, salt.Length); payloadIndex += salt.Length; } //Deriving separate key, might be less efficient than using HKDF, //but now compatible with RNEncryptor which had a very similar wireformat and requires less code than HKDF. using (var generator = new Rfc2898DeriveBytes(password, SaltBitSize / 8, Iterations)) { var salt = generator.Salt; //Generate Keys authKey = generator.GetBytes(KeyBitSize / 8); //Create Rest of Non Secret Payload Array.Copy(salt, 0, payload, payloadIndex, salt.Length); } return SimpleEncrypt(secretMessage, cryptKey, authKey, payload); } public static byte[] SimpleDecryptWithPassword(byte[] encryptedMessage, string password, int nonSecretPayloadLength = 0) { //User Error Checks if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength) throw new ArgumentException(String.Format("Must have a password of at least {0} characters!", MinPasswordLength), "password"); if (encryptedMessage == null || encryptedMessage.Length == 0) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); var cryptSalt = new byte[SaltBitSize / 8]; var authSalt = new byte[SaltBitSize / 8]; //Grab Salt from Non-Secret Payload Array.Copy(encryptedMessage, nonSecretPayloadLength, cryptSalt, 0, cryptSalt.Length); Array.Copy(encryptedMessage, nonSecretPayloadLength + cryptSalt.Length, authSalt, 0, authSalt.Length); byte[] cryptKey; byte[] authKey; //Generate crypt key using (var generator = new Rfc2898DeriveBytes(password, cryptSalt, Iterations)) { cryptKey = generator.GetBytes(KeyBitSize / 8); } //Generate auth key using (var generator = new Rfc2898DeriveBytes(password, authSalt, Iterations)) { authKey = generator.GetBytes(KeyBitSize / 8); } return SimpleDecrypt(encryptedMessage, cryptKey, authKey, cryptSalt.Length + authSalt.Length + nonSecretPayloadLength); } } }

Castillo hinchable AES-GCM [Gist]

/* * This work (Modern Encryption of a String C#, by James Tuley), * identified by James Tuley, is free of known copyright restrictions. * https://gist.github.com/4336842 * http://creativecommons.org/publicdomain/mark/1.0/ */ using System; using System.IO; using System.Text; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; namespace Encryption { public static class AESGCM { private static readonly SecureRandom Random = new SecureRandom(); //Preconfigured Encryption Parameters public static readonly int NonceBitSize = 128; public static readonly int MacBitSize = 128; public static readonly int KeyBitSize = 256; //Preconfigured Password Key Derivation Parameters public static readonly int SaltBitSize = 128; public static readonly int Iterations = 10000; public static readonly int MinPasswordLength = 12; /// <summary> /// Helper that generates a random new key on each call. /// </summary> /// <returns></returns> public static byte[] NewKey() { var key = new byte[KeyBitSize / 8]; Random.NextBytes(key); return key; } /// <summary> /// Simple Encryption And Authentication (AES-GCM) of a UTF8 string. /// </summary> /// <param name="secretMessage">The secret message.</param> /// <param name="key">The key.</param> /// <param name="nonSecretPayload">Optional non-secret payload.</param> /// <returns> /// Encrypted Message /// </returns> /// <exception cref="System.ArgumentException">Secret Message Required!;secretMessage</exception> /// <remarks> /// Adds overhead of (Optional-Payload + BlockSize(16) + Message + HMac-Tag(16)) * 1.33 Base64 /// </remarks> public static string SimpleEncrypt(string secretMessage, byte[] key, byte[] nonSecretPayload = null) { if (string.IsNullOrEmpty(secretMessage)) throw new ArgumentException("Secret Message Required!", "secretMessage"); var plainText = Encoding.UTF8.GetBytes(secretMessage); var cipherText = SimpleEncrypt(plainText, key, nonSecretPayload); return Convert.ToBase64String(cipherText); } /// <summary> /// Simple Decryption & Authentication (AES-GCM) of a UTF8 Message /// </summary> /// <param name="encryptedMessage">The encrypted message.</param> /// <param name="key">The key.</param> /// <param name="nonSecretPayloadLength">Length of the optional non-secret payload.</param> /// <returns>Decrypted Message</returns> public static string SimpleDecrypt(string encryptedMessage, byte[] key, int nonSecretPayloadLength = 0) { if (string.IsNullOrEmpty(encryptedMessage)) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); var cipherText = Convert.FromBase64String(encryptedMessage); var plainText = SimpleDecrypt(cipherText, key, nonSecretPayloadLength); return plainText == null ? null : Encoding.UTF8.GetString(plainText); } /// <summary> /// Simple Encryption And Authentication (AES-GCM) of a UTF8 String /// using key derived from a password (PBKDF2). /// </summary> /// <param name="secretMessage">The secret message.</param> /// <param name="password">The password.</param> /// <param name="nonSecretPayload">The non secret payload.</param> /// <returns> /// Encrypted Message /// </returns> /// <remarks> /// Significantly less secure than using random binary keys. /// Adds additional non secret payload for key generation parameters. /// </remarks> public static string SimpleEncryptWithPassword(string secretMessage, string password, byte[] nonSecretPayload = null) { if (string.IsNullOrEmpty(secretMessage)) throw new ArgumentException("Secret Message Required!", "secretMessage"); var plainText = Encoding.UTF8.GetBytes(secretMessage); var cipherText = SimpleEncryptWithPassword(plainText, password, nonSecretPayload); return Convert.ToBase64String(cipherText); } /// <summary> /// Simple Decryption and Authentication (AES-GCM) of a UTF8 message /// using a key derived from a password (PBKDF2) /// </summary> /// <param name="encryptedMessage">The encrypted message.</param> /// <param name="password">The password.</param> /// <param name="nonSecretPayloadLength">Length of the non secret payload.</param> /// <returns> /// Decrypted Message /// </returns> /// <exception cref="System.ArgumentException">Encrypted Message Required!;encryptedMessage</exception> /// <remarks> /// Significantly less secure than using random binary keys. /// </remarks> public static string SimpleDecryptWithPassword(string encryptedMessage, string password, int nonSecretPayloadLength = 0) { if (string.IsNullOrWhiteSpace(encryptedMessage)) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); var cipherText = Convert.FromBase64String(encryptedMessage); var plainText = SimpleDecryptWithPassword(cipherText, password, nonSecretPayloadLength); return plainText == null ? null : Encoding.UTF8.GetString(plainText); } public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] key, byte[] nonSecretPayload = null) { //User Error Checks if (key == null || key.Length != KeyBitSize / 8) throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key"); if (secretMessage == null || secretMessage.Length == 0) throw new ArgumentException("Secret Message Required!", "secretMessage"); //Non-secret Payload Optional nonSecretPayload = nonSecretPayload ?? new byte[] { }; //Using random nonce large enough not to repeat var nonce = new byte[NonceBitSize / 8]; Random.NextBytes(nonce, 0, nonce.Length); var cipher = new GcmBlockCipher(new AesFastEngine()); var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload); cipher.Init(true, parameters); //Generate Cipher Text With Auth Tag var cipherText = new byte[cipher.GetOutputSize(secretMessage.Length)]; var len = cipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0); cipher.DoFinal(cipherText, len); //Assemble Message using (var combinedStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(combinedStream)) { //Prepend Authenticated Payload binaryWriter.Write(nonSecretPayload); //Prepend Nonce binaryWriter.Write(nonce); //Write Cipher Text binaryWriter.Write(cipherText); } return combinedStream.ToArray(); } } public static byte[] SimpleDecrypt(byte[] encryptedMessage, byte[] key, int nonSecretPayloadLength = 0) { //User Error Checks if (key == null || key.Length != KeyBitSize / 8) throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key"); if (encryptedMessage == null || encryptedMessage.Length == 0) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); using (var cipherStream = new MemoryStream(encryptedMessage)) using (var cipherReader = new BinaryReader(cipherStream)) { //Grab Payload var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength); //Grab Nonce var nonce = cipherReader.ReadBytes(NonceBitSize / 8); var cipher = new GcmBlockCipher(new AesFastEngine()); var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload); cipher.Init(false, parameters); //Decrypt Cipher Text var cipherText = cipherReader.ReadBytes(encryptedMessage.Length - nonSecretPayloadLength - nonce.Length); var plainText = new byte[cipher.GetOutputSize(cipherText.Length)]; try { var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0); cipher.DoFinal(plainText, len); } catch (InvalidCipherTextException) { //Return null if it doesn''t authenticate return null; } return plainText; } } public static byte[] SimpleEncryptWithPassword(byte[] secretMessage, string password, byte[] nonSecretPayload = null) { nonSecretPayload = nonSecretPayload ?? new byte[] {}; //User Error Checks if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength) throw new ArgumentException(String.Format("Must have a password of at least {0} characters!", MinPasswordLength), "password"); if (secretMessage == null || secretMessage.Length == 0) throw new ArgumentException("Secret Message Required!", "secretMessage"); var generator = new Pkcs5S2ParametersGenerator(); //Use Random Salt to minimize pre-generated weak password attacks. var salt = new byte[SaltBitSize / 8]; Random.NextBytes(salt); generator.Init( PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()), salt, Iterations); //Generate Key var key = (KeyParameter)generator.GenerateDerivedMacParameters(KeyBitSize); //Create Full Non Secret Payload var payload = new byte[salt.Length + nonSecretPayload.Length]; Array.Copy(nonSecretPayload, payload, nonSecretPayload.Length); Array.Copy(salt,0, payload,nonSecretPayload.Length, salt.Length); return SimpleEncrypt(secretMessage, key.GetKey(), payload); } public static byte[] SimpleDecryptWithPassword(byte[] encryptedMessage, string password, int nonSecretPayloadLength = 0) { //User Error Checks if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength) throw new ArgumentException(String.Format("Must have a password of at least {0} characters!", MinPasswordLength), "password"); if (encryptedMessage == null || encryptedMessage.Length == 0) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); var generator = new Pkcs5S2ParametersGenerator(); //Grab Salt from Payload var salt = new byte[SaltBitSize / 8]; Array.Copy(encryptedMessage, nonSecretPayloadLength, salt, 0, salt.Length); generator.Init( PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()), salt, Iterations); //Generate Key var key = (KeyParameter)generator.GenerateDerivedMacParameters(KeyBitSize); return SimpleDecrypt(encryptedMessage, key.GetKey(), salt.Length + nonSecretPayloadLength); } } }


Algoritmo AES:

public static class CryptographyProvider { public static string EncryptString(string plainText, out string Key) { if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException("plainText"); using (Aes _aesAlg = Aes.Create()) { Key = Convert.ToBase64String(_aesAlg.Key); ICryptoTransform _encryptor = _aesAlg.CreateEncryptor(_aesAlg.Key, _aesAlg.IV); using (MemoryStream _memoryStream = new MemoryStream()) { _memoryStream.Write(_aesAlg.IV, 0, 16); using (CryptoStream _cryptoStream = new CryptoStream(_memoryStream, _encryptor, CryptoStreamMode.Write)) { using (StreamWriter _streamWriter = new StreamWriter(_cryptoStream)) { _streamWriter.Write(plainText); } return Convert.ToBase64String(_memoryStream.ToArray()); } } } } public static string DecryptString(string cipherText, string Key) { if (string.IsNullOrEmpty(cipherText)) throw new ArgumentNullException("cipherText"); if (string.IsNullOrEmpty(Key)) throw new ArgumentNullException("Key"); string plaintext = null; byte[] _initialVector = new byte[16]; byte[] _Key = Convert.FromBase64String(Key); byte[] _cipherTextBytesArray = Convert.FromBase64String(cipherText); byte[] _originalString = new byte[_cipherTextBytesArray.Length - 16]; Array.Copy(_cipherTextBytesArray, 0, _initialVector, 0, _initialVector.Length); Array.Copy(_cipherTextBytesArray, 16, _originalString, 0, _cipherTextBytesArray.Length - 16); using (Aes _aesAlg = Aes.Create()) { _aesAlg.Key = _Key; _aesAlg.IV = _initialVector; ICryptoTransform decryptor = _aesAlg.CreateDecryptor(_aesAlg.Key, _aesAlg.IV); using (MemoryStream _memoryStream = new MemoryStream(_originalString)) { using (CryptoStream _cryptoStream = new CryptoStream(_memoryStream, decryptor, CryptoStreamMode.Read)) { using (StreamReader _streamReader = new StreamReader(_cryptoStream)) { plaintext = _streamReader.ReadToEnd(); } } } } return plaintext; } }


Aquí está un simple fragmento de código originalmente por ASP fragmentos de código

using System.Text; using System.Security.Cryptography; using System.IO; private string Encrypt(string clearText) { string EncryptionKey = "yourkey"; byte[] clearBytes = Encoding.Unicode.GetBytes(clearText); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(clearBytes, 0, clearBytes.Length); cs.Close(); } clearText = Convert.ToBase64String(ms.ToArray()); } } return clearText; } private string Decrypt(string cipherText) { string EncryptionKey = "yourkey"; cipherText = cipherText.Replace(" ", "+"); byte[] cipherBytes = Convert.FromBase64String(cipherText); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherBytes, 0, cipherBytes.Length); cs.Close(); } cipherText = Encoding.Unicode.GetString(ms.ToArray()); } } return cipherText; }


Cifrado

public string EncryptString(string inputString) { MemoryStream memStream = null; try { byte[] key = { }; byte[] IV = { 12, 21, 43, 17, 57, 35, 67, 27 }; string encryptKey = "aXb2uy4z"; // MUST be 8 characters key = Encoding.UTF8.GetBytes(encryptKey); byte[] byteInput = Encoding.UTF8.GetBytes(inputString); DESCryptoServiceProvider provider = new DESCryptoServiceProvider(); memStream = new MemoryStream(); ICryptoTransform transform = provider.CreateEncryptor(key, IV); CryptoStream cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write); cryptoStream.Write(byteInput, 0, byteInput.Length); cryptoStream.FlushFinalBlock(); } catch (Exception ex) { Response.Write(ex.Message); } return Convert.ToBase64String(memStream.ToArray()); }

Descifrado:

public string DecryptString(string inputString) { MemoryStream memStream = null; try { byte[] key = { }; byte[] IV = { 12, 21, 43, 17, 57, 35, 67, 27 }; string encryptKey = "aXb2uy4z"; // MUST be 8 characters key = Encoding.UTF8.GetBytes(encryptKey); byte[] byteInput = new byte[inputString.Length]; byteInput = Convert.FromBase64String(inputString); DESCryptoServiceProvider provider = new DESCryptoServiceProvider(); memStream = new MemoryStream(); ICryptoTransform transform = provider.CreateDecryptor(key, IV); CryptoStream cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write); cryptoStream.Write(byteInput, 0, byteInput.Length); cryptoStream.FlushFinalBlock(); } catch (Exception ex) { Response.Write(ex.Message); } Encoding encoding1 = Encoding.UTF8; return encoding1.GetString(memStream.ToArray()); }


Este es un ejemplo simple de cifrado de cadenas en C # usando el modo AES CBC con IV y HMAC aleatorios y claves derivadas de contraseña, para mostrar las partes móviles básicas:

private byte[] EncryptBytes(byte[] key, byte[] plaintext) { using (var cipher = new RijndaelManaged { Key = key }) { using (var encryptor = cipher.CreateEncryptor()) { var ciphertext = encryptor.TransformFinalBlock(plaintext, 0, plaintext.Length); // IV is prepended to ciphertext return cipher.IV.Concat(ciphertext).ToArray(); } } } private byte[] DecryptBytes(byte[] key, byte[] packed) { using (var cipher = new RijndaelManaged { Key = key }) { int ivSize = cipher.BlockSize / 8; cipher.IV = packed.Take(ivSize).ToArray(); using (var encryptor = cipher.CreateDecryptor()) { return encryptor.TransformFinalBlock(packed, ivSize, packed.Length - ivSize); } } } private byte[] AddMac(byte[] key, byte[] data) { using (var hmac = new HMACSHA256(key)) { var macBytes = hmac.ComputeHash(data); // HMAC is appended to data return data.Concat(macBytes).ToArray(); } } private bool BadMac(byte[] found, byte[] computed) { int mismatch = 0; // Aim for consistent timing regardless of inputs for (int i = 0; i < found.Length; i++) { mismatch += found[i] == computed[i] ? 0 : 1; } return mismatch != 0; } private byte[] RemoveMac(byte[] key, byte[] data) { using (var hmac = new HMACSHA256(key)) { int macSize = hmac.HashSize / 8; var packed = data.Take(data.Length - macSize).ToArray(); var foundMac = data.Skip(packed.Length).ToArray(); var computedMac = hmac.ComputeHash(packed); if (this.BadMac(foundMac, computedMac)) { throw new Exception("Bad MAC"); } return packed; } } private List<byte[]> DeriveTwoKeys(string password) { var salt = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; var kdf = new Rfc2898DeriveBytes(password, salt, 10000); var bytes = kdf.GetBytes(32); // Two keys 128 bits each return new List<byte[]> { bytes.Take(16).ToArray(), bytes.Skip(16).ToArray() }; } public byte[] EncryptString(string password, String message) { var keys = this.DeriveTwoKeys(password); var plaintext = Encoding.UTF8.GetBytes(message); var packed = this.EncryptBytes(keys[0], plaintext); return this.AddMac(keys[1], packed); } public String DecryptString(string password, byte[] secret) { var keys = this.DeriveTwoKeys(password); var packed = this.RemoveMac(keys[1], secret); var plaintext = this.DecryptBytes(keys[0], packed); return Encoding.UTF8.GetString(plaintext); } public void Example() { var password = "correcthorsebatterystaple"; var secret = this.EncryptString(password, "Hello World"); Console.WriteLine("secret: " + BitConverter.ToString(secret)); var recovered = this.DecryptString(password, secret); Console.WriteLine(recovered); }


Si está utilizando ASP.Net, ahora puede usar la funcionalidad incorporada en .Net 4.0 en adelante.

System.Web.Security.MachineKey

.Net 4.5 tiene MachineKey.Protect()y MachineKey.Unprotect().

.Net 4.0 tiene MachineKey.Encode()y MachineKey.Decode(). Solo debes configurar MachineKeyProtection en ''Todos''.

Fuera de ASP.Net, esta clase parece generar una nueva clave con cada reinicio de la aplicación, por lo que no funciona. Con un vistazo rápido en ILSpy, me parece que genera sus propios valores predeterminados si faltan las aplicaciones adecuadas. Por lo tanto, es posible que pueda configurarlo fuera de ASP.Net.

No he podido encontrar un equivalente que no sea ASP.Net fuera del espacio de nombres de System.Web.


para simplificar, hice para mí esta función que utilizo para propósitos no criptográficos: reemplace "frase de contraseña" con su contraseña ...

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.IO; namespace My { public class strCrypto { // This constant string is used as a "salt" value for the PasswordDeriveBytes function calls. // This size of the IV (in bytes) must = (keysize / 8). Default keysize is 256, so the IV must be // 32 bytes long. Using a 16 character string here gives us 32 bytes when converted to a byte array. private const string initVector = "r5dm5fgm24mfhfku"; private const string passPhrase = "yourpassphrase"; // email password encryption password // This constant is used to determine the keysize of the encryption algorithm. private const int keysize = 256; public static string encryptString(string plainText) { //if the plaintext is empty or null string just return an empty string if (plainText == "" || plainText == null ) { return ""; } byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector); byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null); byte[] keyBytes = password.GetBytes(keysize / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes); MemoryStream memoryStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write); cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); byte[] cipherTextBytes = memoryStream.ToArray(); memoryStream.Close(); cryptoStream.Close(); return Convert.ToBase64String(cipherTextBytes); } public static string decryptString(string cipherText) { //if the ciphertext is empty or null string just return an empty string if (cipherText == "" || cipherText == null ) { return ""; } byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); byte[] cipherTextBytes = Convert.FromBase64String(cipherText); PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null); byte[] keyBytes = password.GetBytes(keysize / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes); MemoryStream memoryStream = new MemoryStream(cipherTextBytes); CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); byte[] plainTextBytes = new byte[cipherTextBytes.Length]; int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); memoryStream.Close(); cryptoStream.Close(); return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); } }

}


Con la referencia de Encriptar y Descifrar una Cadena en c # , encontré una de buena solución:

static readonly string PasswordHash = "P@@Sw0rd"; static readonly string SaltKey = "S@LT&KEY"; static readonly string VIKey = "@1B2c3D4e5F6g7H8";

Para encriptar

public static string Encrypt(string plainText) { byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8); var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros }; var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey)); byte[] cipherTextBytes; using (var memoryStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); cipherTextBytes = memoryStream.ToArray(); cryptoStream.Close(); } memoryStream.Close(); } return Convert.ToBase64String(cipherTextBytes); }

Para descifrar

public static string Decrypt(string encryptedText) { byte[] cipherTextBytes = Convert.FromBase64String(encryptedText); byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8); var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None }; var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey)); var memoryStream = new MemoryStream(cipherTextBytes); var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); byte[] plainTextBytes = new byte[cipherTextBytes.Length]; int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); memoryStream.Close(); cryptoStream.Close(); return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("/0".ToCharArray()); }


Copiado en mi answer aquí de una pregunta similar: Cifrado simple de dos vías para C # .

Basado en múltiples respuestas y comentarios.

  • Vector de inicialización aleatorio ante texto criptográfico (@jbtule)
  • Use TransformFinalBlock () en lugar de MemoryStream (@RenniePet)
  • No hay claves precargadas para evitar que alguien copie y pegue un desastre
  • Disposición adecuada y uso de patrones.

Código:

/// <summary> /// Simple encryption/decryption using a random initialization vector /// and prepending it to the crypto text. /// </summary> /// <remarks>Based on multiple answers in https://.com/questions/165808/simple-two-way-encryption-for-c-sharp </remarks> public class SimpleAes : IDisposable { /// <summary> /// Initialization vector length in bytes. /// </summary> private const int IvBytes = 16; /// <summary> /// Must be exactly 16, 24 or 32 characters long. /// </summary> private static readonly byte[] Key = Convert.FromBase64String("FILL ME WITH 16, 24 OR 32 CHARS"); private readonly UTF8Encoding _encoder; private readonly ICryptoTransform _encryptor; private readonly RijndaelManaged _rijndael; public SimpleAes() { _rijndael = new RijndaelManaged {Key = Key}; _rijndael.GenerateIV(); _encryptor = _rijndael.CreateEncryptor(); _encoder = new UTF8Encoding(); } public string Decrypt(string encrypted) { return _encoder.GetString(Decrypt(Convert.FromBase64String(encrypted))); } public void Dispose() { _rijndael.Dispose(); _encryptor.Dispose(); } public string Encrypt(string unencrypted) { return Convert.ToBase64String(Encrypt(_encoder.GetBytes(unencrypted))); } private byte[] Decrypt(byte[] buffer) { // IV is prepended to cryptotext byte[] iv = buffer.Take(IvBytes).ToArray(); using (ICryptoTransform decryptor = _rijndael.CreateDecryptor(_rijndael.Key, iv)) { return decryptor.TransformFinalBlock(buffer, IvBytes, buffer.Length - IvBytes); } } private byte[] Encrypt(byte[] buffer) { // Prepend cryptotext with IV byte[] inputBuffer = _rijndael.IV.Concat(buffer).ToArray(); return _encryptor.TransformFinalBlock(inputBuffer, IvBytes, buffer.Length); } }


Descargo de responsabilidad: esta solución solo debe utilizarse para datos en reposo que no estén expuestos al público (por ejemplo, un archivo de configuración o DB). Solo en este escenario, la solución rápida y sucia se puede considerar mejor que la solución de @jbtule, debido a un menor mantenimiento.

https://.com/a/10366194/188474 original: encontré la respuesta de https://.com/a/10366194/188474 un poco complicada para un cifrado AES seguro y sucio, y la respuesta de share tuvo un error con el Vector de Inicialización como un valor fijo que lo hace vulnerable a ataques de relleno, así que arreglé el código de Brett y se agregó un IV aleatorio que se agrega a la cadena chipered, creando un valor cifrado diferente para cada cifrado del mismo valor:

Cifrado

public static string Encrypt(string clearText) { byte[] clearBytes = Encoding.Unicode.GetBytes(clearText); using (Aes encryptor = Aes.Create()) { byte[] IV = new byte[15]; rand.NextBytes(IV); Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(clearBytes, 0, clearBytes.Length); cs.Close(); } clearText = Convert.ToBase64String(IV) + Convert.ToBase64String(ms.ToArray()); } } return clearText; }

Descifrado:

public static string Decrypt(string cipherText) { byte[] IV = Convert.FromBase64String(cipherText.Substring(0, 20)); cipherText = cipherText.Substring(20).Replace(" ", "+"); byte[] cipherBytes = Convert.FromBase64String(cipherText); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherBytes, 0, cipherBytes.Length); cs.Close(); } cipherText = Encoding.Unicode.GetString(ms.ToArray()); } } return cipherText; }

Reemplace EncryptionKey con su clave. En mi implementación, la clave se está guardando en el archivo de configuración (web.config / app.config), ya que no debería guardarlo en el código. El archivo de configuración también debe estar cifrado para que la clave no se guarde como texto sin cifrar .

protected static string _Key = ""; protected static string EncryptionKey { get { if (String.IsNullOrEmpty(_Key)) { _Key = ConfigurationManager.AppSettings["AESKey"].ToString(); } return _Key; } }


El cifrado es un asunto muy común en la programación. Creo que es mejor instalar un paquete para que haga la tarea por usted. Tal vez un simple proyecto de código abierto Nuget como Simple Aes Encryption

La clave está en el archivo de configuración y, por lo tanto, es fácil de cambiar en el entorno de producción, y no veo inconvenientes

<MessageEncryption> <EncryptionKey KeySize="256" Key="3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu8="/> </MessageEncryption>


Esta es la clase que fue colocada aquí por Brett. Sin embargo, hice una pequeña edición ya que estaba recibiendo el error ''Longitud no válida para una matriz de caracteres Base-64'' cuando lo utilizaba para cadenas URL para cifrar y descifrar.

public class CryptoURL { private static byte[] _salt = Encoding.ASCII.GetBytes("Catto_Salt_Enter_Any_Value99"); /// <summary> /// Encrypt the given string using AES. The string can be decrypted using /// DecryptStringAES(). The sharedSecret parameters must match. /// The SharedSecret for the Password Reset that is used is in the next line /// string sharedSecret = "OneUpSharedSecret9"; /// </summary> /// <param name="plainText">The text to encrypt.</param> /// <param name="sharedSecret">A password used to generate a key for encryption.</param> public static string EncryptString(string plainText, string sharedSecret) { if (string.IsNullOrEmpty(plainText)) throw new ArgumentNullException("plainText"); if (string.IsNullOrEmpty(sharedSecret)) throw new ArgumentNullException("sharedSecret"); string outStr = null; // Encrypted string to return RijndaelManaged aesAlg = null; // RijndaelManaged object used to encrypt the data. try { // generate the key from the shared secret and the salt Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt); // Create a RijndaelManaged object aesAlg = new RijndaelManaged(); aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); // Create a decryptor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { // prepend the IV msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int)); msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length); using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); } } outStr = HttpServerUtility.UrlTokenEncode(msEncrypt.ToArray()); //outStr = Convert.ToBase64String(msEncrypt.ToArray()); // you may need to add a reference. right click reference in solution explorer => "add Reference" => .NET tab => select "System.Web" } } finally { // Clear the RijndaelManaged object. if (aesAlg != null) aesAlg.Clear(); } // Return the encrypted bytes from the memory stream. return outStr; } /// <summary> /// Decrypt the given string. Assumes the string was encrypted using /// EncryptStringAES(), using an identical sharedSecret. /// </summary> /// <param name="cipherText">The text to decrypt.</param> /// <param name="sharedSecret">A password used to generate a key for decryption.</param> public static string DecryptString(string cipherText, string sharedSecret) { if (string.IsNullOrEmpty(cipherText)) throw new ArgumentNullException("cipherText"); if (string.IsNullOrEmpty(sharedSecret)) throw new ArgumentNullException("sharedSecret"); // Declare the RijndaelManaged object // used to decrypt the data. RijndaelManaged aesAlg = null; // Declare the string used to hold // the decrypted text. string plaintext = null; byte[] inputByteArray; try { // generate the key from the shared secret and the salt Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt); // Create the streams used for decryption. //byte[] bytes = Convert.FromBase64String(cipherText); inputByteArray = HttpServerUtility.UrlTokenDecode(cipherText); using (MemoryStream msDecrypt = new MemoryStream(inputByteArray)) { // Create a RijndaelManaged object // with the specified key and IV. aesAlg = new RijndaelManaged(); aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); // Get the initialization vector from the encrypted stream aesAlg.IV = ReadByteArray(msDecrypt); // Create a decrytor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) // Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } catch (System.Exception ex) { return "ERROR"; //throw ex; } finally { // Clear the RijndaelManaged object. if (aesAlg != null) aesAlg.Clear(); } return plaintext; } static string ConvertStringArrayToString(string[] array) { // // Concatenate all the elements into a StringBuilder. // StringBuilder builder = new StringBuilder(); foreach (string value in array) { builder.Append(value); builder.Append(''.''); } return builder.ToString(); } private static byte[] ReadByteArray(Stream s) { byte[] rawLength = new byte[sizeof(int)]; if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length) { throw new SystemException("Stream did not contain properly formatted byte array"); } byte[] buffer = new byte[BitConverter.ToInt32(rawLength, 0)]; if (s.Read(buffer, 0, buffer.Length) != buffer.Length) { throw new SystemException("Did not read byte array properly"); } return buffer; } }


Para apoyar la respuesta de mattmanser . Aquí hay un ejemplo que usa la clase MachineKey para cifrar / descifrar valores seguros de URL.

Algo a tener en cuenta, como se mencionó anteriormente, esto usará los ajustes de configuración de la Máquina ( https://msdn.microsoft.com/en-us/library/ff649308.aspx ). Puede configurar la clave / algoritmo de cifrado y descifrado manualmente (es posible que lo necesite especialmente si su sitio se ejecuta en varios servidores) en el archivo web.config. Puede generar claves desde IIS (consulte aquí: https://blogs.msdn.microsoft.com/vijaysk/2009/05/13/iis-7-tip-10-you-can-generate-machine-keys-from-the-iis-manager/ ) o puede usar un generador de claves de máquina en línea como: http://www.developerfusion.com/tools/generatemachinekey/

private static readonly UTF8Encoding Encoder = new UTF8Encoding(); public static string Encrypt(string unencrypted) { if (string.IsNullOrEmpty(unencrypted)) return string.Empty; try { var encryptedBytes = MachineKey.Protect(Encoder.GetBytes(unencrypted)); if (encryptedBytes != null && encryptedBytes.Length > 0) return HttpServerUtility.UrlTokenEncode(encryptedBytes); } catch (Exception) { return string.Empty; } return string.Empty; } public static string Decrypt(string encrypted) { if (string.IsNullOrEmpty(encrypted)) return string.Empty; try { var bytes = HttpServerUtility.UrlTokenDecode(encrypted); if (bytes != null && bytes.Length > 0) { var decryptedBytes = MachineKey.Unprotect(bytes); if(decryptedBytes != null && decryptedBytes.Length > 0) return Encoder.GetString(decryptedBytes); } } catch (Exception) { return string.Empty; } return string.Empty; }


Quiero darle mi contribución, con mi código para AES Rfc2898DeriveBytes( here la documentación) algorhytm, escrito en C # (.NET framework 4) y totalmente operativo también para plataformas limitadas, como .NET Compact Framework para Windows Phone 7.0+ (no todos las plataformas soportan todos los métodos criptográficos de .NET framework!).

Espero que esto pueda ayudar a cualquiera!

using System; using System.IO; using System.Security.Cryptography; using System.Text; public static class Crypto { private static readonly byte[] IVa = new byte[] { 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x11, 0x12, 0x13, 0x14, 0x0e, 0x16, 0x17 }; public static string Encrypt(this string text, string salt) { try { using (Aes aes = new AesManaged()) { Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(Encoding.UTF8.GetString(IVa, 0, IVa.Length), Encoding.UTF8.GetBytes(salt)); aes.Key = deriveBytes.GetBytes(128 / 8); aes.IV = aes.Key; using (MemoryStream encryptionStream = new MemoryStream()) { using (CryptoStream encrypt = new CryptoStream(encryptionStream, aes.CreateEncryptor(), CryptoStreamMode.Write)) { byte[] cleanText = Encoding.UTF8.GetBytes(text); encrypt.Write(cleanText, 0, cleanText.Length); encrypt.FlushFinalBlock(); } byte[] encryptedData = encryptionStream.ToArray(); string encryptedText = Convert.ToBase64String(encryptedData); return encryptedText; } } } catch { return String.Empty; } } public static string Decrypt(this string text, string salt) { try { using (Aes aes = new AesManaged()) { Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(Encoding.UTF8.GetString(IVa, 0, IVa.Length), Encoding.UTF8.GetBytes(salt)); aes.Key = deriveBytes.GetBytes(128 / 8); aes.IV = aes.Key; using (MemoryStream decryptionStream = new MemoryStream()) { using (CryptoStream decrypt = new CryptoStream(decryptionStream, aes.CreateDecryptor(), CryptoStreamMode.Write)) { byte[] encryptedData = Convert.FromBase64String(text); decrypt.Write(encryptedData, 0, encryptedData.Length); decrypt.Flush(); } byte[] decryptedData = decryptionStream.ToArray(); string decryptedText = Encoding.UTF8.GetString(decryptedData, 0, decryptedData.Length); return decryptedText; } } } catch { return String.Empty; } } } }



Tienes que usar el espacio de nombres usando System.Security.Cryptography; y useHashing es un tipo bool verdadero o falso. La variable de cadena "clave" debe ser la misma para el cifrado y para el descifrado

//Encryption public string EncryptText(string toEncrypt, bool useHashing) { try { byte[] keyArray; byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); string key = "String Key Value"; //Based on this key stirng is encrypting //System.Windows.Forms.MessageBox.Show(key); //If hashing use get hashcode regards to your key if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); //Always release the resources and flush data //of the Cryptographic service provide. Best Practice hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); //set the secret key for the tripleDES algorithm tdes.Key = keyArray; //mode of operation. there are other 4 modes. We choose ECB(Electronic code Book) tdes.Mode = CipherMode.ECB; //padding mode(if any extra byte added) tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateEncryptor(); //transform the specified region of bytes array to resultArray byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); //Release resources held by TripleDes Encryptor tdes.Clear(); //Return the encrypted data into unreadable string format return Convert.ToBase64String(resultArray, 0, resultArray.Length); } catch (Exception e) { throw e; } } //Decryption public string DecryptText(string cipherString, bool useHashing) { try { byte[] keyArray; //get the byte code of the string byte[] toEncryptArray = Convert.FromBase64String(cipherString); string key = "String Key Value"; //Based on this key string is decrypted if (useHashing) { //if hashing was used get the hash code with regards to your key MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); //release any resource held by the MD5CryptoServiceProvider hashmd5.Clear(); } else { //if hashing was not implemented get the byte code of the key keyArray = UTF8Encoding.UTF8.GetBytes(key); } TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); //set the secret key for the tripleDES algorithm tdes.Key = keyArray; //mode of operation. there are other 4 modes. //We choose ECB(Electronic code Book) tdes.Mode = CipherMode.ECB; //padding mode(if any extra byte added) tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length); //Release resources held by TripleDes Encryptor tdes.Clear(); //return the Clear decrypted TEXT return UTF8Encoding.UTF8.GetString(resultArray); } catch (Exception ex) { throw ex; } }


Un buen algoritmo para hash de datos de forma BCrypt es BCrypt :

Además de incorporar una sal para proteger contra los ataques de la tabla del arco iris, bcrypt es una función adaptativa: con el tiempo, se puede aumentar el recuento de iteraciones para hacerlo más lento, por lo que sigue siendo resistente a los ataques de búsqueda de fuerza bruta, incluso con una potencia de cálculo creciente.

Hay una buena implementación .NET de BCrypt que también está disponible como paquete NuGet .


Una alternativa a BouncyCastle para el AES-GCM es libsodium-net . Envuelve la biblioteca C de libsodium. Una buena ventaja es que utiliza la extensión AES-NI en las CPU para un cifrado muy rápido. El lado negativo es que no funcionará en absoluto si la CPU no tiene la extensión. No hay software de retroceso.


using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; // This is for password validation using System.Security.Cryptography; using System.Configuration; // This is where the hash functions reside namespace BullyTracker.Common { public class HashEncryption { //public string GenerateHashvalue(string thisPassword) //{ // MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); // byte[] tmpSource; // byte[] tmpHash; // tmpSource = ASCIIEncoding.ASCII.GetBytes(thisPassword); // Turn password into byte array // tmpHash = md5.ComputeHash(tmpSource); // StringBuilder sOutput = new StringBuilder(tmpHash.Length); // for (int i = 0; i < tmpHash.Length; i++) // { // sOutput.Append(tmpHash[i].ToString("X2")); // X2 formats to hexadecimal // } // return sOutput.ToString(); //} //public Boolean VerifyHashPassword(string thisPassword, string thisHash) //{ // Boolean IsValid = false; // string tmpHash = GenerateHashvalue(thisPassword); // Call the routine on user input // if (tmpHash == thisHash) IsValid = true; // Compare to previously generated hash // return IsValid; //} public string GenerateHashvalue(string toEncrypt, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); // Get the key from config file string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); //System.Windows.Forms.MessageBox.Show(key); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } /// <summary> /// DeCrypt a string using dual encryption method. Return a DeCrypted clear string /// </summary> /// <param name="cipherString">encrypted string</param> /// <param name="useHashing">Did you use hashing to encrypt this data? pass true is yes</param> /// <returns></returns> public string Decrypt(string cipherString, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(cipherString); System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); //Get your key from config file to open the lock! string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); return UTF8Encoding.UTF8.GetString(resultArray); } } }


using System; using System.Data; using System.Configuration; using System.Text; using System.Security.Cryptography; namespace Encription { class CryptorEngine { public static string Encrypt(string ToEncrypt, bool useHasing) { byte[] keyArray; byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(ToEncrypt); //System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); string Key = "Bhagwati"; if (useHasing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(Key)); hashmd5.Clear(); } else { keyArray = UTF8Encoding.UTF8.GetBytes(Key); } TripleDESCryptoServiceProvider tDes = new TripleDESCryptoServiceProvider(); tDes.Key = keyArray; tDes.Mode = CipherMode.ECB; tDes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tDes.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tDes.Clear(); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } public static string Decrypt(string cypherString, bool useHasing) { byte[] keyArray; byte[] toDecryptArray = Convert.FromBase64String(cypherString); //byte[] toEncryptArray = Convert.FromBase64String(cypherString); //System.Configuration.AppSettingsReader settingReader = new AppSettingsReader(); string key = "Bhagwati"; if (useHasing) { MD5CryptoServiceProvider hashmd = new MD5CryptoServiceProvider(); keyArray = hashmd.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd.Clear(); } else { keyArray = UTF8Encoding.UTF8.GetBytes(key); } TripleDESCryptoServiceProvider tDes = new TripleDESCryptoServiceProvider(); tDes.Key = keyArray; tDes.Mode = CipherMode.ECB; tDes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tDes.CreateDecryptor(); try { byte[] resultArray = cTransform.TransformFinalBlock(toDecryptArray, 0, toDecryptArray.Length); tDes.Clear(); return UTF8Encoding.UTF8.GetString(resultArray,0,resultArray.Length); } catch (Exception ex) { throw ex; } } } }


using System; using System.IO; using System.Security.Cryptography; using System.Text; public class Program { public static void Main() { var key = Encoding.UTF8.GetBytes("SUkbqO2ycDo7QwpR25kfgmC7f8CoyrZy"); var data = Encoding.UTF8.GetBytes("testData"); //Encrypt data var encrypted = CryptoHelper.EncryptData(data,key); //Decrypt data var decrypted = CryptoHelper.DecryptData(encrypted,key); //Display result Console.WriteLine(Encoding.UTF8.GetString(decrypted)); } } public static class CryptoHelper { public static byte[] EncryptData(byte[] data, byte[] key) { using (var aesAlg = Aes.Create()) { aesAlg.Mode = CipherMode.CBC; using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV)) { using (var msEncrypt = new MemoryStream()) { msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length); using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) csEncrypt.Write(data, 0, data.Length); return msEncrypt.ToArray(); } } } } public static byte[] DecryptData(byte[] encrypted, byte[] key) { var iv = new byte[16]; Buffer.BlockCopy(encrypted, 0, iv, 0, iv.Length); using (var aesAlg = Aes.Create()) { aesAlg.Mode = CipherMode.CBC; using (var decryptor = aesAlg.CreateDecryptor(key, iv)) { using (var msDecrypt = new MemoryStream(encrypted, iv.Length, encrypted.Length - iv.Length)) { using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (var resultStream = new MemoryStream()) { csDecrypt.CopyTo(resultStream); return resultStream.ToArray(); } } } } } } }