एन्क्रिप्ट करें और C # में एक स्ट्रिंग को डिक्रिप्ट करें?


694

मैं C # में स्ट्रिंग को कैसे एन्क्रिप्ट और डिक्रिप्ट कर सकता हूं?


2
इस लिंक की जाँच करें codeproject.com/KB/recipes/Encrypt_an_string.aspx
डेवलपर

3
कुछ सरल चाहिए ... इस लिंक ने मेरे लिए काम किया saipanyam.net/2010/03/encrypt-query-strings.html
MrM

6
मैं अत्यधिक 3DES छोड़ने और AES-GCM का उपयोग करने की सलाह दूंगा। AES-GCM .NET 4.5 क्रिप्टोकरंसी और IS में 'सामान्य AES' (आमतौर पर AES-CBC मोड) से अलग नहीं पाया जाता है। AES-GCM क्रिप्टोग्राफिक कारण के लिए 'सामान्य' AES की तुलना में कहीं बेहतर है, जिसमें मैं नहीं जाऊंगा। तो jbtuleइस Bouncy Castle AES-GCMउपधारा के नीचे सबसे अच्छा जवाब है । आप हमें विश्वास नहीं करते हैं, तो कम से कम विश्वास पर एनएसए में विशेषज्ञ (एनएसए सुइट बी @ nsa.gov/ia/programs/suiteb_cryptography/index.shtml : The Galois/Counter Mode (GCM) is the preferred AES mode.)
DeepSpace101

1
@ व्यक्तिगत रूप से मैं अधिकांश स्थितियों के लिए एईएस-जीसीएम पर एईएस-सीबीसी + एचएमएसी-एसएचए 2 पसंद करूंगा। यदि आप कभी गैर का उपयोग करते हैं तो GCM विनाशकारी रूप से विफल हो जाता है।
कोडइन्चोज

2
@Sid Nonce का पुन: उपयोग एक बुरा विचार है, हाँ। लेकिन मैंने देखा है कि ऐसा होता है, यहां तक ​​कि सक्षम प्रोग्रामर / क्रिप्टोग्राफर के साथ भी। यदि ऐसा होता है, तो जीसीएम पूरी तरह से टूट जाता है, जबकि सीबीसी + एचएमएसी केवल कुछ छोटी कमजोरियों को विकसित करता है। प्रोटोकॉल जैसे SSL के साथ GCM ठीक है, लेकिन मैं मानक "एन्क्रिप्ट और प्रमाणित" एपीआई के रूप में इसके साथ सहज नहीं हूं।
कोडइन्चोज

जवाबों:


415

EDIT 2013-Oct : हालाँकि मैंने कमियों को दूर करने के लिए इस उत्तर को समय के साथ संपादित किया है, कृपया अधिक मजबूत, सूचित समाधान के लिए jbtule का उत्तर देखें ।

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

मूल उत्तर:

यहां "रिज्डेलमनेज्ड क्लास" प्रलेखन और एमसीटीएस प्रशिक्षण किट से प्राप्त एक कामकाजी उदाहरण है ।

EDIT 2012-अप्रैल : इस उत्तर को jbtule के सुझाव के अनुसार IV को प्री-पेंड करने के लिए संपादित किया गया था और जैसा कि यहाँ चित्रित किया गया है:

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

सौभाग्य!

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;
    }
}

3
ब्रेट के लिए - अपने उदाहरण के लिए हाय thx। मेयबी एक सोचते हैं - मेरे पास कुंजी लेंग के साथ मुद्दा था - मैंने एमडी 5 के साथ संशोधन किया, इसलिए यदि कोई व्यक्ति आपके उदाहरण का उपयोग सुविधा में करेगा, तो कुंजी सामान्यीकरण के लिए इसका उपयोग करें (या आप अन्य हैश अल्गोरिटम का उपयोग कर सकते हैं: HashAlivem हैश = नया MD5CryptoServiceProvider (); यूनिकोडएन्कोडिंग यूई = नया यूनिकोडेन्कोडिंग (); बाइट [] कुंजी = हैश। कॉमप्यूटहैश (यूई.गेटबाइट्स (एनक्रिप्ट_पासवर्ड)); पीएस: मेरे अंग्रेजी के लिए खेद है :) slinti

18
उपरोक्त कोड सुरक्षित नहीं है, यह एईएस के साथ सिमेंटिक सुरक्षा के सबसे बुनियादी नियम को तोड़ता है, आपको एक ही कुंजी के साथ एक से अधिक बार एक ही IV का उपयोग नहीं करना चाहिए। यह हमेशा एक समान IV देता है जब भी आप एक ही कुंजी का उपयोग करते हैं।
22

7
की-व्युत्पत्ति प्रक्रिया में नमक का उपयोग करने से चोट नहीं पहुंचेगी। एक स्थिरांक एक अच्छा नमक नहीं है, जैसे स्थिरांक एक अच्छा IV नहीं है।
कोडइन्चोस

5
एईएस बनाम रिजिन्देल भ्रम की स्थिति: एईएस रिजेंडेल का सबसेट है। यदि आप 128 बिट ब्लॉक और या तो 128, 192 या 256 बिट कुंजियों के साथ रिजेंडेल का उपयोग करते हैं, तो आप एईएस का उपयोग कर रहे हैं।
कोडइन्चोस

3
खुर को रोकने के लिए नमक एक हद तक obfuscation जोड़ता है। अनुशंसा करें कि आप नीचे दिए गए jbtules उदाहरण पढ़ें जहां नमक उत्पन्न होता है।
ब्रेट

360

एक स्ट्रिंग के सममित प्रामाणिक एन्क्रिप्शन के आधुनिक उदाहरण।

सममित एन्क्रिप्शन के लिए सामान्य सर्वोत्तम अभ्यास एसोसिएटेड डेटा (AEAD) के साथ प्रमाणीकरण एन्क्रिप्शन का उपयोग करना है, हालांकि यह मानक .net क्रिप्टो पुस्तकालयों का हिस्सा नहीं है। तो पहला उदाहरण AES256 और उसके बाद HMAC256 , एक दो कदम Encrypt तो मैक का उपयोग करता है , जिसके लिए अधिक ओवरहेड और अधिक कुंजी की आवश्यकता होती है।

दूसरा उदाहरण खुले स्रोत बाउंसी कैसल (नगेट के माध्यम से) का उपयोग करके एईएस 256- जीसीएम के सरल अभ्यास का उपयोग करता है ।

दोनों उदाहरणों में एक मुख्य फ़ंक्शन है जो गुप्त संदेश स्ट्रिंग, कुंजी (एस) और एक वैकल्पिक गैर-गुप्त पेलोड और रिटर्न लेता है और गैर-गुप्त डेटा के साथ वैकल्पिक रूप से प्रचलित एन्क्रिप्टेड स्ट्रिंग को प्रमाणित करता है। आदर्श रूप से आप इनका उपयोग 256bit कुंजी (रों) के साथ यादृच्छिक रूप से उत्पन्न देखेंगे NewKey()

दोनों उदाहरणों में एक सहायक विधियाँ भी हैं जो कुंजियों को उत्पन्न करने के लिए एक स्ट्रिंग पासवर्ड का उपयोग करती हैं। इन सहायक तरीकों को अन्य उदाहरणों के साथ मेल खाने के लिए एक सुविधा के रूप में प्रदान किया जाता है, हालांकि वे बहुत कम सुरक्षित हैं क्योंकि पासवर्ड की ताकत 256 बिट कुंजी की तुलना में बहुत कमज़ोर होने वाली है

अपडेट: अतिरिक्त byte[]अधिभार, और केवल Gist में StackOverflow उत्तर सीमाओं के कारण 4 रिक्त स्थान इंडेंट और एपीआई डॉक्स के साथ पूर्ण स्वरूपण है।


.NET निर्मित-इनक्रिप्ट (एईएस) -थेन-मैक (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);
    }
  }
}

उछालभरी कैसल 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);
    }
  }
}

7
क्या ये नमूने कोड समीक्षा में भी पोस्ट किए गए हैं।
jbtule

3
यह एक अच्छा सवाल है, ये प्रमाणित एन्क्रिप्शन उदाहरणों का उपयोग कर रहे हैं, एन्क्रिप्ट करने के अलावा उनके पास एक मैक है जो यह पुष्टि करने के लिए है कि सिफरटेक्स्ट को किसी और द्वारा संशोधित नहीं किया गया है, यह मुख्य रूप से चुने हुए-सिफरटेक्स्ट हमलों को विफल करना है । इसलिए इसे डिक्रिप्ट करने पर मैक को कैलकुलेट करने के लिए अपीलेटेड एक के खिलाफ जांच करने के लिए कैलकुलेट करता है, अगर यह इसे डिक्रिप्ट करता है और अगर यह नहीं आता है तो यह शून्य हो जाता है।
jbtule

3
मैक पर सरणी चेक हर इंडेक्स करता है, क्योंकि एक फर्जी सिफरटेक्स्ट पर नए मैक की गणना करने के लिए टाइमिंग अटैक का इस्तेमाल किया जा सकता है, अगर यह पहला बाइट देता है जो मैच नहीं करता है।
jbtule

5
यह एक अच्छी किताब है और अपेक्षाकृत हाल की है। मैं और भी अधिक की सिफारिश करेंगे दान बोनह द्वारा मुफ्त ऑनलाइन पाठ्यक्रम क्रिप्टोग्राफी I है। वास्तव में अच्छे वीडियो, वास्तव में अच्छा क्विज़, और वास्तव में अच्छी मशीन समस्याएं भी हैं जो क्रिप्टोग्राफी के उपयोग के लिए एक अच्छा व्यावहारिक आधार प्रदान करती हैं। AesCryptoServiceProvider के संबंध में आपको सबसे अधिक आरामदायक होना चाहिए।
jbtule

8
एक अच्छी तरह से समझाया उपयोग अनुभाग बेहद उपयोगी होगा।
रॉकलन सेप

108

यहाँ RSA का उपयोग करके एक उदाहरण दिया गया है।

महत्वपूर्ण: वहाँ, डेटा आप RSA एन्क्रिप्शन के साथ एन्क्रिप्ट कर सकते हैं के आकार की एक सीमा होती है KeySize - MinimumPaddingउदाहरण के लिए 256 बाइट्स (2048 बिट कुंजी मानकर) - 42 बाइट्स (न्यूनतम OEAP पैडिंग) = 214 बाइट्स (अधिकतम सादे आकार)

अपने RSA कुंजी के साथ अपने_rsa_key को बदलें।

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));

अधिक जानकारी के लिए, MSDN - RSACryptoServiceProvider देखें


7
इस तरह के एक साधारण सवाल पूछने के लिए क्षमा करें, लेकिन क्या कोई मुझे बता सकता है कि मुझे आरएसए कुंजी कहां मिलती है या मैं एक कैसे उत्पन्न कर सकता हूं?
आकाश काव

11
RSA क्यों? आरएसए के इसके उपयोग हैं, लेकिन कुछ भी संकेत नहीं दिया कि यह उनमें से एक है।
कोडइंचौस

39
यहां तक ​​कि मूल प्रश्न में कोई संकेत नहीं है कि RSAएक अच्छा फिट हो सकता है। असममित एन्क्रिप्शन के इसके उपयोग हैं, लेकिन यह डिफ़ॉल्ट एन्क्रिप्शन के रूप में सही विकल्प नहीं है। आपका उदाहरण कोड लंबी स्ट्रिंग के लिए विफल हो जाएगा क्योंकि RSA वर्ग सामान्य उद्देश्य एन्क्रिप्शन के लिए डिज़ाइन नहीं किया गया है। यदि आपको असममित विशेषताओं की आवश्यकता है, तो आपको RSA के साथ एक सममित कुंजी को एन्क्रिप्ट करना चाहिए और उस सममित कुंजी के साथ वास्तविक डेटा को एन्क्रिप्ट करना चाहिए। इसलिए मुझे अभी भी विश्वास है कि आपका उत्तर बुरी सलाह है।
कोडइन्चोस

9
मैं एक गलत जवाब के लिए 70 वोटों से प्रभावित हूं, जैसा कि CodesInChaos ने कहा है कि इस प्रकार के एन्क्रिप्शन के लिए आपको एक सममित कुंजी की आवश्यकता होती है, न कि एक एसिमिट्रिक की।
ओटो कानेलिस

5
यह एक गलत जवाब नहीं है, बस एक विशाल ओवरहेड के साथ अधिक जटिल है ... बेहतर परिणामों के लिए एईएस / किसी भी अन्य सममित तरीकों का उपयोग करें।
तोमर डब्ल्यू

54

यदि आप ASP.Net का उपयोग कर रहे हैं, तो अब आप .Net 4.0 के बाद कार्यक्षमता में निर्मित का उपयोग कर सकते हैं।

System.Web.Security.MachineKey

.नेट 4.5 MachineKey.Protect()और है MachineKey.Unprotect()

.Net 4.0 MachineKey.Encode()और है MachineKey.Decode()। आपको बस मशीनकेप्रोटेक्शन को 'ऑल' में सेट करना चाहिए।

ASP.Net के बाहर यह वर्ग हर ऐप रीस्टार्ट के साथ एक नई कुंजी उत्पन्न करता है, इसलिए यह काम नहीं करता है। ILSpy में एक त्वरित झांकने के साथ यह मुझे ऐसा लगता है जैसे यह उपयुक्त ऐप। सेट गायब होने पर अपनी स्वयं की चूक उत्पन्न करता है। तो आप वास्तव में इसे ASP.Net के बाहर स्थापित करने में सक्षम हो सकते हैं।

मैं System.Web नाम स्थान के बाहर एक गैर-ASP.Net समकक्ष नहीं खोज सका।


हम्म कोई मुझे बता सकता है कि इस जवाब में इतने कम वोट क्यों हैं? यह ASP.NET अनुप्रयोगों के लिए एक बहुत ही सुविधाजनक तरीका लगता है
डिर्क बोअर

@DirkBoer कार्यक्षमता को सवाल पूछे जाने के कुछ साल बाद जोड़ा गया था, मैंने इस सवाल के लिए अपना जवाब जोड़ा कि लोगों को आज आसान तरीके बताए जा सकते हैं। यह भी केवल कुछ ऐप के बिना ASP.Net के साथ काम करता है ।config-fu जो काफी खतरनाक है यदि आप नहीं जानते कि आप क्या कर रहे हैं।
मैटमनर

3
मेरे अज्ञान को क्षमा करें लेकिन वेब पेज से मैं अपने उत्तर का पता नहीं लगा सकता। यदि मैं एक मशीन पर एक स्ट्रिंग को एन्क्रिप्ट करता हूं, तो इसे डेटाबेस में लिखें, और इसे किसी अन्य मशीन के साथ पढ़ें क्या मैं इसे तब तक डिक्रिप्ट कर पाऊंगा जब तक कि उद्देश्य पैरामीटर समान मूल्य नहीं हैं? शायद मैं "मशीनकेय" नाम से भ्रमित हूं
एड्रियन डेवेल

एक और सवाल, क्या मैं इसे WPF ऐप में इस्तेमाल कर सकता हूं? इसका कोई वेब संदर्भ नहीं है, क्या System.Web के संदर्भ जोड़ना ठीक है?
एड्रियन डावल

2
@AdriaanDavel लिंक किए गए डॉक्स के अनुसार, "मशीनकेक एपीआई का उपयोग केवल एक ASP.NET ऐप में किया जाना चाहिए। ASP.NET एप्लिकेशन के संदर्भ के बाहर मशीनके एपीआई का व्यवहार अपरिभाषित है" इसका उपयोग केवल तभी करें जब आप गेम का आनंद लें। रूसी रूले
मार्क सोउल

47

BouncyCastle .NET के लिए एक महान क्रिप्टो लाइब्रेरी है, यह आपकी परियोजनाओं में स्थापित करने के लिए Nuget पैकेज के रूप में उपलब्ध है । मुझे यह बहुत पसंद है कि वर्तमान में System.Security.Cryptography लाइब्रेरी में क्या उपलब्ध है। यह आपको उपलब्ध एल्गोरिदम के संदर्भ में बहुत अधिक विकल्प प्रदान करता है, और उन एल्गोरिदम के लिए और अधिक मोड प्रदान करता है।

यह टू फिश के कार्यान्वयन का एक उदाहरण है , जिसे ब्रूस श्नियर (हीरो ने हम सभी लोगों को वहाँ से बाहर निकालने के लिए लिखा था) द्वारा लिखा गया था । यह रिजेंडेल (उर्फ एईएस) की तरह एक सममित एल्गोरिथम है। यह एईएस मानक के लिए तीन फाइनलिस्टों में से एक था और ब्रूस श्नेयर द्वारा ब्लोविश नामक एक अन्य प्रसिद्ध एल्गोरिथ्म के लिए सिबलिंग था।

बाउंसाइक्लस्टल के साथ पहली बात यह है कि एक एनक्रिप्टर्स क्लास बनाया जाए, इससे लाइब्रेरी के भीतर अन्य ब्लॉक सिफर को लागू करना आसान हो जाएगा। निम्न एनक्रिप्टर्स क्लास एक सामान्य तर्क टी में ले जाता है, जहां टी IBlockCipher को लागू करता है और एक डिफ़ॉल्ट कंस्ट्रक्टर है।

अद्यतन: लोकप्रिय मांग के कारण मैंने एक यादृच्छिक IV उत्पन्न करने के साथ-साथ इस वर्ग में HMAC को शामिल करने का निर्णय लिया है। हालांकि एक शैली के नजरिए से यह एकल जिम्मेदारी के ठोस सिद्धांत के खिलाफ जाता है, क्योंकि इस वर्ग के स्वभाव के कारण मैं इसका नाम बदल देता हूं। यह वर्ग अब दो सामान्य पैरामीटर लेगा, एक सिफर के लिए और दूसरा डाइजेस्ट के लिए। यह स्वचालित रूप से अच्छा RNG एन्ट्रापी प्रदान करने के लिए RNGCryptoServiceProvider का उपयोग करके IV उत्पन्न करता है, और आपको MAC उत्पन्न करने के लिए BouncyCastle से जो भी डाइजेस्ट एल्गोरिथ्म चाहिए, उसका उपयोग करने की अनुमति देता है।

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;
    }
}

अगले बस नए वर्ग पर एन्क्रिप्ट और डिक्रिप्ट विधियों को कॉल करें, यहाँ ट्वॉफिश का उपयोग करके उदाहरण दिया गया है:

var encrypt = new Encryptor<TwofishEngine, Sha1Digest>(Encoding.UTF8, key, hmacKey);

string cipher = encrypt.Encrypt("TEST");   
string plainText = encrypt.Decrypt(cipher);

यह सिर्फ ट्रिपलडीईएस की तरह एक और ब्लॉक सिफर विकल्प के लिए आसान है:

var des = new Encryptor<DesEdeEngine, Sha1Digest>(Encoding.UTF8, key, hmacKey);

string cipher = des.Encrypt("TEST");
string plainText = des.Decrypt(cipher);

अंत में यदि आप SHA256 HMAC के साथ AES का उपयोग करना चाहते हैं, तो आप निम्नलिखित कर सकते हैं:

var aes = new Encryptor<AesEngine, Sha256Digest>(Encoding.UTF8, key, hmacKey);

cipher = aes.Encrypt("TEST");
plainText = aes.Decrypt(cipher);

एन्क्रिप्शन के बारे में सबसे कठिन हिस्सा वास्तव में कुंजियों से संबंधित है न कि एल्गोरिदम से। आपको यह सोचना होगा कि आप अपनी कुंजियाँ कहाँ संग्रहित करते हैं, और यदि आपको करना है, तो आप उनका आदान-प्रदान कैसे करेंगे। इन एल्गोरिदम में सभी समय की कसौटी पर खरे उतरे हैं, और तोड़ने के लिए बेहद कठिन हैं। कोई व्यक्ति जो आपसे जानकारी चुराना चाहता है, वह आपके संदेशों पर क्रिप्टैनालिसिस कर रहे अनंत काल बिताने नहीं जा रहा है, वे यह पता लगाने की कोशिश करने जा रहे हैं कि आपकी कुंजी क्या है या कहाँ है। इसलिए # 1 अपनी चाबियाँ बुद्धिमानी से चुनें, # 2 उन्हें सुरक्षित स्थान पर स्टोर करें, यदि आप web.config और IIS का उपयोग करते हैं तो आप web.config के कुछ हिस्सों को एन्क्रिप्ट कर सकते हैं , और अंत में यदि आपको कुंजियों का आदान-प्रदान करना है तो सुनिश्चित करें कि आपका कुंजी के आदान-प्रदान के लिए प्रोटोकॉल सुरक्षित है।

अद्यतन 2 समयबद्ध हमलों के खिलाफ कम करने के लिए विधि की तुलना में परिवर्तन करें। अधिक जानकारी यहाँ देखें http://codahale.com/a-lesson-in-timing-attacks/ । पीकेसीएस 7 पैडिंग के लिए डिफ़ॉल्ट रूप से अपडेट किया गया और अंतिम उपयोगकर्ता को जोड़ा गया ताकि अंतिम उपयोगकर्ता को यह चुनने की क्षमता मिल सके कि वे किस पैडिंग का उपयोग करना चाहते हैं। धन्यवाद @CodesInChaos सुझाव के लिए।


3
1) उस वर्ग का उपयोग करने के लिए बहुत कष्टप्रद है क्योंकि आप उपयोगकर्ता पर IV प्रबंधन का बोझ डालते हैं जो लगभग निश्चित रूप से गलत होगा। 2) मैक का अभाव इस oracles को गद्दी के लिए कमजोर बनाता है।
कोडइन्कॉउंस

3
1) आपकी पैडिंग मुझे टूटी हुई लगती है। आप एक शून्य पैडिंग जोड़ते हैं और इसे हटाते नहीं हैं। शून्य गद्दी एक बुरा विचार है क्योंकि इसे मज़बूती से नहीं हटाया जा सकता है। इसके बजाय PKCS # 7 पैडिंग का उपयोग करें। मैं पहले से ही इस समर्थन के लिए b Councilycastle एन्क्रिप्शन / डिक्रिप्शन फ़ंक्शन की अपेक्षा करता हूं। 2) आपको मैक को मान्य करने के लिए एक निरंतर समय की तुलना का उपयोग करना चाहिए, न कि SequenceEqual। यह एक टाइम-साइड-चैनल से बचा जाता है जो कि प्रस्तुत मैक और वास्तविक मैक मैच के एक उपसर्ग को कितनी देर तक लीक करता है।
कोडइन्चोस

2
@CodesInChaos मैं सहमत हूं, इस जाँच के लिए धन्यवाद कि मैंने इन युगल मुद्दों को हल करने के लिए एक संपादन किया है। - nerdybeardo
nerdybeardo

महान जवाब, सिर्फ एक सवाल .... क्या कुंजी और hmacKey, मैं crypto..thanks के लिए नया हूँ!
टेराकोस

1
@Terkhos आपको RNGCryptoServiceProvider जैसी कुंजियाँ बनाने के लिए एक सुरक्षित यादृच्छिक संख्या जनरेटर का उपयोग करना चाहिए, आपको कभी भी पासफ़्रेज़ या किसी पूर्वानुमानित चीज़ का उपयोग नहीं करना चाहिए। आपको अधिकतम लंबाई का भी उपयोग करना चाहिए जो एल्गोरिथ्म उदाहरण के लिए प्रदान करेगा एईएस 256 एक महत्वपूर्ण आकार का उपयोग करता है जो लंबाई में 256 बिट्स है इसलिए 32 यादृच्छिक बाइट्स सबसे अच्छा होगा, एचएमएसी प्रमुख आकार आमतौर पर एसएचए 2 के लिए एल्गोरिथ्म के आकार पर आधारित होते हैं ( 256) सुरक्षित यादृच्छिक संख्या जनरेटर द्वारा उत्पन्न 256 बिट कुंजी पर्याप्त होगी। अक्सर चाबियाँ बदलें! अधिक बार बेहतर!
nerdybeardo

18

डिस्क्लेमर: इस समाधान का उपयोग केवल उन डेटा के लिए किया जाना चाहिए, जो जनता के सामने उजागर नहीं होते हैं (उदाहरण के लिए - एक कॉन्फ़िगरेशन फ़ाइल या DB)। केवल इस परिदृश्य में, त्वरित और गंदे समाधान को मेनटेनेंस के कारण @ jbtule के समाधान से बेहतर माना जा सकता है।

मूल पोस्ट: मैंने jbtule के उत्तर को एक त्वरित और गंदे सुरक्षित एईएस स्ट्रिंग एन्क्रिप्शन के लिए थोड़ा जटिल पाया है और ब्रेट के उत्तर में बग के साथ एक बग था जिसमें वेक्टर एक निश्चित मूल्य होता है जो इसे पैडिंग हमलों के लिए असुरक्षित बनाता है, इसलिए मैंने ब्रेट का कोड और एक यादृच्छिक IV जोड़ा गया जो चिपके स्ट्रिंग में जोड़ा जाता है, एक ही मूल्य के प्रत्येक एन्क्रिप्शन को एक अलग एन्क्रिप्टेड मूल्य बनाता है:

एन्क्रिप्शन:

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;
}

डिक्रिप्शन:

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;
}

एन्क्रिप्शन कुंजी को अपनी कुंजी से बदलें। मेरे कार्यान्वयन में, कुंजी को कॉन्फ़िगरेशन फ़ाइल (web.config \ app.config) में सहेजा जा रहा है क्योंकि आपको इसे हार्ड कोडित नहीं करना चाहिए। कॉन्फ़िगरेशन फ़ाइल को भी एन्क्रिप्ट किया जाना चाहिए ताकि कुंजी को इसमें स्पष्ट पाठ के रूप में सहेजा न जाए।

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

        return _Key;
    }
}

1
जबकि आपकी Encryptविधि हर कॉल के लिए समान सादे पाठ के साथ भी एक अलग मान उत्पन्न करती है, Substring(20)क्या हर बार एक ही होगा, है ना?
डब स्टाइल

आपका क्या मतलब है "वही"? डिक्रिप्ट फ़ंक्शन एन्क्रिप्शन मूल्य द्वारा उत्पन्न हर मूल्य लेता है, इसे आरंभीकरण वेक्टर और एन्क्रिप्टेड मूल्य के अलावा तोड़ता है और इसे डिक्रिप्ट करता है,
गिल कोहेन

1
मैंने देखा कि Encryptहर बार एक अलग IV उत्पन्न नहीं हुआ। किसी कारण से मैं सोच रहा था कि IV हर बार वही था, जो मूल रूप से इसे व्यर्थ कर देगा।
डब स्टाइल

1
@GilCohen ने इस पर एक बड़ा खुलासा किया और कहा कि केवल आराम के लिए डेटा का उपयोग करें, एक सेवा के साथ उजागर न करें और फिर आप जोखिम प्रबंधन का दावा कर सकते हैं। हालाँकि , आपका त्वरित और गंदा सिर्फ मैला है। उदाहरण के लिए, आप केवल डिक्रिप्ट पर प्लस संकेतों के साथ रिक्त स्थान क्यों बदलते हैं और इसके विपरीत नहीं है, क्या यह इसलिए है क्योंकि आपके मिलने से पहले कुछ और सिफरटेक्स्ट को संशोधित कर रहा है? एक url क्वेरी स्ट्रिंग, कुकी या फ़ॉर्म वैरिएबल, hmm से गुजरने की तरह, यह एक सेवा की तरह लगता है, जो कि तब होता है जब आपको सिफर टेक्स्ट को प्रमाणित करने की आवश्यकता होती है
jbtule

2
@jbtule वास्तव में नहीं, यह किसी कारण से Base64 फ़ंक्शन का एन्कोडिंग है। यह वास्तव में आराम के लिए डेटा के लिए उपयोग किया गया था और मैं आपकी टिप्पणी से सहमत हूं। मैं इसे जोड़ दूँगा।
गिल कोहेन

12

एन्क्रिप्शन

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());
}

डिक्रिप्शन:

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());
}

8
-1 यह बहुत कमजोर है। 1) डेस बल को 56 बिट कुंजी के लिए आसान करना है। 2) एक कुंजी बाइनरी है, न कि UTF8। यदि कुंजी में ASCII वर्ण (व्यवहार में संभावना) हैं, तो यह प्रभावी कुंजी आकार को 48 बिट तक कम कर देता है। 3) प्रत्येक संदेश के लिए एक IV अलग होना चाहिए 4) मैक के अभाव से आप सक्रिय हमलों के लिए खुल जाते हैं, जिसमें गद्दी या गद्दी शामिल हैं।
कोडइन्चोस

9
+1 ओपी के पास अधिकतम सरलता के लिए आवश्यकता के बिना एक बहुत ही सरल प्रश्न था, और यह उत्तर पूरी तरह से मेल खाता है। कम से कम मैं इसका उपयोग कर सकता हूं क्योंकि मेरे पास एन्क्रिप्शन के लिए एक सरल उपयोग भी है।
रोलैंड

-1 @Roland जैसा कि संहिताओं द्वारा बताया गया है, एक IV को प्रत्येक संदेश के लिए अलग-अलग होने की आवश्यकता है, बहुत ही सरलता से, यदि ऐसा नहीं है, तो आप एपीआई का गलत तरीके से उपयोग कर रहे हैं, इसलिए इस कोड का उपयोग कभी नहीं किया जाना चाहिए। अवधि। 48bit कुंजी को ओवरशैडो करने के लिए नहीं, यह केवल एक दिन में कुंजी के बिना किसी को भी डिक्रिप्ट करने योग्य है, इसलिए यह अब एन्क्रिप्शन नहीं है और इस प्रकार प्रश्न का उत्तर नहीं देता है।
jbtule

@jbtule धन्यवाद, मैं अपने एन्क्रिप्शन प्रोजेक्ट की समीक्षा करते समय अन्य उत्तरों पर गंभीरता से विचार करूंगा।
रोलैंड

2
सरल अनुप्रयोगों के लिए इसका उपयोग करें यदि आप परमाणु रहस्यों की रक्षा कर रहे हैं, तो कुछ और उपयोग करें। यह इस प्रकार है।
जॉन पिटावे सेप

6

C # में Encrypt और Decrypt a String के संदर्भ में , मुझे एक अच्छा समाधान मिला:

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

एनक्रिप्ट के लिए

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);
}

डिक्रिप्ट के लिए

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());
}

7
हार्डकोडेड साल्ट और IV, और उनके लिए ASCII प्रतिनिधित्व का उपयोग करना, यह सभी प्रकार की गलत है।
जब्बुल

7
सुरक्षा चेतावनी: इस कोड का उपयोग न करें मेरी टिप्पणी ऊपर देखें।
jbtule

6
मैं माफी माँगता हूँ कि मैंने यह नहीं बताया। IV एक कुंजी नहीं है, और इसे गुप्त रखने से शून्य अतिरिक्त सुरक्षा मिलती है, और यह अनुमान लगाने योग्य सुरक्षा का एक बहुत कुछ खो देता है। IV को हार्डकोड करना किसी के लिए पूरी तरह से अनुचित / अतार्किक / गलत है जो वास्तव में AES-CBC एन्क्रिप्शन का उपयोग करना जानता है। Encoding.ASCII.GetBytesऐसे डेटा के लिए जिसे मानव द्वारा चुने गए किसी चीज़ में एन्ट्रॉपी जोड़ने का इरादा है, वह कम होने जा रहा है और फिर उम्मीद की तुलना में एन्ट्रॉपी है और यह बहुत ही गलत है। ये सभी चीजें हैं जो आसानी से सुधारात्मक हैं, लेकिन आप नहीं हैं, इसलिए सुरक्षा निहितार्थ के कारण मेरी साहसिक चेतावनी जारी है।
jbtule

4
राहुल, चिल! वापस बैठें, आराम करें और सोचें कि @jbtule की सभी 3 टिप्पणियों को वोट क्यों मिले। आपको सही रास्ते पर लाने के लिए वह कुछ समझदार बात कर रहा है। कुछ भी महसूस नहीं हुआ। आप एसओ के लिए नए हैं। आपको एहसास होगा कि यह आखिरकार कैसे काम करता है।
निखिल वर्तक

5

निम्न उदाहरण दर्शाता है कि नमूना डेटा को एन्क्रिप्ट और डिक्रिप्ट कैसे करें:

    // This constant is used to determine the keysize of the encryption algorithm in bits.
    // We divide this by 8 within the code below to get the equivalent number of bytes.
    private const int Keysize = 128;

    // This constant determines the number of iterations for the password bytes generation function.
    private const int DerivationIterations = 1000;

    public static string Encrypt(string plainText, string passPhrase)
    {
        // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
        // so that the same Salt and IV values can be used when decrypting.  
        var saltStringBytes = GenerateBitsOfRandomEntropy(16);
        var ivStringBytes = GenerateBitsOfRandomEntropy(16);
        var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
        {
            var keyBytes = password.GetBytes(Keysize / 8);
            using (var symmetricKey = new RijndaelManaged())
            {
                symmetricKey.BlockSize = 128;
                symmetricKey.Mode = CipherMode.CBC;
                symmetricKey.Padding = PaddingMode.PKCS7;
                using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
                            var cipherTextBytes = saltStringBytes;
                            cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
                            cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
                            memoryStream.Close();
                            cryptoStream.Close();
                            return Convert.ToBase64String(cipherTextBytes);
                        }
                    }
                }
            }
        }
    }

    public static string Decrypt(string cipherText, string passPhrase)
    {
        // Get the complete stream of bytes that represent:
        // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
        var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
        // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
        var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
        // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
        var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
        // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
        var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();

        using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
        {
            var keyBytes = password.GetBytes(Keysize / 8);
            using (var symmetricKey = new RijndaelManaged())
            {
                symmetricKey.BlockSize = 128;
                symmetricKey.Mode = CipherMode.CBC;
                symmetricKey.Padding = PaddingMode.PKCS7;
                using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
                {
                    using (var memoryStream = new MemoryStream(cipherTextBytes))
                    {
                        using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            var plainTextBytes = new byte[cipherTextBytes.Length];
                            var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                            memoryStream.Close();
                            cryptoStream.Close();
                            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                        }
                    }
                }
            }
        }
    }

    private static byte[] GenerateBitsOfRandomEntropy(int size)
    {
        // 32 Bytes will give us 256 bits.
        // 16 Bytes will give us 128 bits.
        var randomBytes = new byte[size]; 
        using (var rngCsp = new RNGCryptoServiceProvider())
        {
            // Fill the array with cryptographically secure random bytes.
            rngCsp.GetBytes(randomBytes);
        }
        return randomBytes;
    }

धन्यवाद @reza .. अगर मैं कर सकता हूँ कुछ घर परियोजनाओं के लिए इसका इस्तेमाल करने वाला?
अर्री

4

मैटमनसर उत्तर का समर्थन करने के लिए । यहां URL सुरक्षित मूल्यों को एन्क्रिप्ट / डिक्रिप्ट करने के लिए MachineKey क्लास का उपयोग करके एक उदाहरण दिया गया है।

कुछ को ध्यान में रखना, जैसा कि पहले उल्लेख किया गया है, यह मशीन कॉन्फ़िगरेशन सेटिंग्स ( https://msdn.microsoft.com/en-us/library/ff649308.aspx ) का उपयोग करेगा । आप एन्क्रिप्शन और डिक्रिप्शन कुंजी / एल्गोरिथ्म को मैन्युअल रूप से सेट कर सकते हैं (आपको इसकी विशेष रूप से आवश्यकता हो सकती है अगर आपकी साइट कई सर्वरों पर चल रही है) web.config फ़ाइल में। आप IIS से कुंजी उत्पन्न कर सकते हैं (यहाँ देखें: https://blogs.msdn.microsoft.com/vijaysk/2009/05/13/iis-7-tip-10-you-can-generate-machine-keys-from/ i-iis-manager / ) या ऑनलाइन मशीन कुंजी जनरेटर का उपयोग कर सकते हैं जैसे: 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;
    }

3

यहाँ मूल चलती भागों को दिखाने के लिए यादृच्छिक IV और HMAC और पासवर्ड-व्युत्पन्न कुंजियों के साथ AES CBC मोड का उपयोग करके C # में स्ट्रिंग एन्क्रिप्ट करने का एक सरल उदाहरण है:

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);
}

3
मुद्दों की एक जोड़ी: 1) आप कुंजी व्युत्पत्ति में एक नमक का उपयोग नहीं कर रहे हैं, बहु लक्ष्य हमलों को सक्षम कर रहे हैं। 2) आपका मैक तुलना समारोह संभावित रूप से साइड-चैनल / टाइमिंग हमलों के लिए असुरक्षित है क्योंकि आप गुप्त डेटा पर शाखा करते हैं। mismatch += found[i]^computed[i]इसके बजाय कुछ का उपयोग करें । 3) आप PBKDF2-HMAC-SHA-1 के 20 से अधिक बाइट्स का उपयोग कर रहे हैं, जो आपके केडीएफ को एक हमलावर द्वारा धीमा किए बिना 2 के कारक से धीमा कर देता है
कोडइन्कॉउंस

1
@CodesInChaos: 1) यह लोगों को आरंभ करने के लिए एक सरल उदाहरण के रूप में था - मैं केवल स्पष्टता के लिए यादृच्छिक नमक छोड़ता हूं। लेकिन, अच्छी बात है। 2) अच्छा, सूक्ष्म बिंदु। 3) बीस बाइट्स में दो 16 बाइट कीज़ निकालने के लिए आप क्या सुझाव देते हैं?
जिम फ्लड

सबसे सरल तरीका है SHA-2 के साथ धीमी हैश का उत्पादन हैशिंग। फैनसीयर तरीके LOF या बस PBKDF2 को फिर से लागू करने के लिए हैं, लेकिन इस बार पुनरावृत्तियों के साथ सेट करने के लिए 1.
CodeInChaos

@CodesInChaos मैं SHA-2 का उपयोग नहीं करता। हैश फ़ंक्शन का कार्य कुंजी व्युत्पत्ति फ़ंक्शन के कार्य के समान नहीं है। एक हैश को केवल अप्रत्याशित होने की जरूरत है, और इनपुट बदलने पर बदलने के लिए। एक प्रमुख को यादृच्छिक से अप्रभेद्य होना चाहिए। मैं अभी भी केडीएफ से 32 बाइट निकालूंगा। इस मामले में, आप बहुत जल्दी अनुकूलन कर रहे हैं और जोखिम जोड़ रहे हैं।
जिम फ्लड

3

एईएस-जीसीएम एन्क्रिप्शन के लिए बाउंसीकैस्टल का एक विकल्प लिबासोडियम-नेट है । यह लिबासोडियम सी लाइब्रेरी को लपेटता है। एक अच्छा लाभ यह है कि यह बहुत तेजी से एन्क्रिप्शन के लिए सीपीयू में एईएस-एनआई एक्सटेंशन का उपयोग करता है। डाउन साइड यह है कि यह बिल्कुल काम नहीं करेगा यदि सीपीयू में एक्सटेंशन नहीं है। कोई सॉफ्टवेयर वापस नहीं है।


3

निम्नलिखित कोड एक समान प्रश्न के ग़ज़ल के उत्तर का एक उन्नत संस्करण है ।

public class EncryptionHelper
{
    private Aes aesEncryptor;

    public EncryptionHelper()
    {
    }

    private void BuildAesEncryptor(string key)
    {
        aesEncryptor = Aes.Create();
        var pdb = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        aesEncryptor.Key = pdb.GetBytes(32);
        aesEncryptor.IV = pdb.GetBytes(16);
    }

    public string EncryptString(string clearText, string key)
    {
        BuildAesEncryptor(key);
        var clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, aesEncryptor.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
            }
            var encryptedText = Convert.ToBase64String(ms.ToArray());
            return encryptedText;
        }
    }

    public string DecryptString(string cipherText, string key)
    {
        BuildAesEncryptor(key);
        cipherText = cipherText.Replace(" ", "+");
        var cipherBytes = Convert.FromBase64String(cipherText);
        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, aesEncryptor.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(cipherBytes, 0, cipherBytes.Length);
            }
            var clearText = Encoding.Unicode.GetString(ms.ToArray());
            return clearText;
        }
    }
}

2

यह वह वर्ग है जिसे ब्रेट ने यहां रखा था। हालाँकि, जब मैंने URL स्ट्रिंग्स को एन्क्रिप्ट और डिक्रिप्ट करने के लिए इसका उपयोग किया था, तब से मुझे एक त्रुटि प्राप्त हुई जब मैं 'आधार-64 चार सरणी के लिए अमान्य लंबाई' त्रुटि प्राप्त कर रहा था।

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;
    }

}

1
किस ConvertStringArrayToString()विधि के लिए प्रयोग किया जाता है?
अबेन्सी

2
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();
                        }
                    }
                }
            }
        }
    }
}

2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
using System.IO;
using System.Text;  

/// <summary>
/// Summary description for Encryption
/// </summary>
public class Encryption
{
    public TripleDES CreateDES(string key)
    {
        MD5 md5 = new MD5CryptoServiceProvider();
        TripleDES des = new TripleDESCryptoServiceProvider();
        des.Key = md5.ComputeHash(Encoding.Unicode.GetBytes(key));
        des.IV = new byte[des.BlockSize / 8];
        return des;
    }
    public  byte[] Encryptiondata(string PlainText)
    {
        TripleDES des = CreateDES("DreamMLMKey");
        ICryptoTransform ct = des.CreateEncryptor();
        byte[] input = Encoding.Unicode.GetBytes(PlainText);
        return ct.TransformFinalBlock(input, 0, input.Length);
    }

    public string Decryptiondata(string CypherText)
    {
        string stringToDecrypt = CypherText.Replace(" ", "+");
        int len = stringToDecrypt.Length;
        byte[] inputByteArray = Convert.FromBase64String(stringToDecrypt); 

        byte[] b = Convert.FromBase64String(CypherText);
        TripleDES des = CreateDES("DreamMLMKey");
        ICryptoTransform ct = des.CreateDecryptor();
        byte[] output = ct.TransformFinalBlock(b, 0, b.Length);
        return Encoding.Unicode.GetString(output);
    }
    public string Decryptiondataurl(string CypherText)
    {
        string newcyperttext=CypherText.Replace(' ', '+');
        byte[] b = Convert.FromBase64String(newcyperttext);
        TripleDES des = CreateDES("DreamMLMKey");
        ICryptoTransform ct = des.CreateDecryptor();
        byte[] output = ct.TransformFinalBlock(b, 0, b.Length);
        return Encoding.Unicode.GetString(output);
    }


    #region  encryption & Decription
    public  string Encrypt(string input, string key)
    {
        byte[] inputArray = UTF8Encoding.UTF8.GetBytes(input);
        TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
        tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
        tripleDES.Mode = CipherMode.ECB;
        tripleDES.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = tripleDES.CreateEncryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
        tripleDES.Clear();
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }
    public  string Decrypt(string input, string key)
    {
        byte[] inputArray = Convert.FromBase64String(input);
        TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
        tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
        tripleDES.Mode = CipherMode.ECB;
        tripleDES.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = tripleDES.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
        tripleDES.Clear();
        return UTF8Encoding.UTF8.GetString(resultArray);
    }

    public string encrypt(string encryptString)
    {
        string EncryptionKey = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        byte[] clearBytes = Encoding.Unicode.GetBytes(encryptString);
        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();
                }
                encryptString = Convert.ToBase64String(ms.ToArray());
            }
        }
        return encryptString;
    }

    public string Decrypt(string cipherText)
    {
        string EncryptionKey = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        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;
    }

    #endregion
}

एमडी 5 सबसे कम सुरक्षित है। यह अनुशंसित नहीं है।
vapcguy

1

एन्क्रिप्शन प्रोग्रामिंग में एक बहुत ही आम बात है। मुझे लगता है कि आपके लिए कार्य करने के लिए पैकेज स्थापित करना बेहतर है। हो सकता है कि सिंपल ओपन सोर्स नुगेट प्रोजेक्ट जैसे सिंपल ऐस एनक्रिप्शन

कॉन्फ़िगरेशन फ़ाइल में कुंजी है और इसलिए उत्पादन वातावरण में परिवर्तन करना आसान है, और मुझे कोई कमियां नहीं दिखती हैं

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

1
बड़ी कमी यह है कि यह प्रमाणित एन्क्रिप्शन नहीं है।
jbtule

0

इसी तरह के प्रश्न से यहाँ मेरे उत्तर में नकल की गई : C # के लिए सरल दो-तरफ़ा एन्क्रिप्शन

कई उत्तरों और टिप्पणियों के आधार पर।

  • रैंडम इनिशियलाइज़ेशन वेक्टर क्रिप्टो टेक्स्ट (@jbtule) से जुड़ा हुआ है
  • MemoryStream (@ RenniePet) के बजाय TransformFinalBlock () का उपयोग करें
  • किसी भी आपदा से बचने और कॉपी करने से पहले की-भरी हुई चाबी नहीं
  • उचित निपटान और पैटर्न का उपयोग करना

कोड:

/// <summary>
/// Simple encryption/decryption using a random initialization vector
/// and prepending it to the crypto text.
/// </summary>
/// <remarks>Based on multiple answers in /programming/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);
    }
}

1
आपको सक्रिय हमलों को रोकने के लिए एक MAC जोड़ना चाहिए, जैसे कि गद्दी oracles।
कोडइन्चोस

आप शायद सही हैं, मैं इस क्षेत्र में किसी भी तरह से कुशल नहीं हूँ। जब मैंने मूल रूप से इस विषय का दौरा किया था तो मुझे बस कुछ सरल चाहिए था जो काम करता है और काफी सुरक्षित है। मैं निश्चित रूप से बहुत संवेदनशील डेटा के लिए एक कोशिश की और सही पुस्तकालय का उपयोग करेंगे।
कोणीय काल

0

यहाँ सरल स्निपेट मूल रूप से एएसपी स्निपेट द्वारा दिया गया है

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;
    }

1
आप अखंडता / प्रमाणीकरण की जाँच नहीं करते हैं। आपको एक मैक जोड़ना चाहिए।
आर्टजोम बी।

आपका वास्तव में क्या मतलब है उपरोक्त उदाहरण स्ट्रिंग चर को एन्क्रिप्ट / डिक्रिप्ट करने के लिए है।
विजय कुंभो

3
पैडिंग ओरेकल हमलों से बचाने के लिए सिफर्टेक्स को प्रमाणित किया जाना चाहिए (जैसे एचएमएसी के साथ)। जब मैं इस कोड को फिर से देखता हूं, तो ऐसा लगता है कि आप ECB मोड का उपयोग कर रहे हैं, जिसका उपयोग कभी नहीं किया जाना चाहिए क्योंकि यह शब्दार्थ रूप से सुरक्षित नहीं है। इसके अलावा, जब आप मास्टर चाबी और नमक से कुंजी और IV प्राप्त करते हैं, तो नमक स्थिर होता है। यह एक स्थिर IV की ओर जाता है जो IV की पूरी अवधारणा को तोड़ता है और आपकी योजना को फिर से असुरक्षित बनाता है।
आर्टजोम बी।

धन्यवाद भाई, अगर आप यहाँ सही कोड पास कर सकते हैं तो बहुत मदद मिलेगी।
विजय कुंभो

0

एईएस एल्गोरिथम:

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;
        }
    }

1) IV को एक पैरामीटर के रूप में पारित किया जाता है जिसका अर्थ है कि डेवलपर को IV प्रबंधन करना है और वे इसे गलत करेंगे । इसके बजाय, IV को सिफरटेक्स्ट के साथ बेतरतीब ढंग से उत्पन्न और संग्रहीत किया जाना चाहिए। 2) चूंकि IV और कुंजी Encryptionविधि के कई निष्पादन के बीच बदल जाएगी और बनी नहीं रहती है, इसलिए प्रदर्शन उद्देश्यों के लिए इस पद्धति को अन्य सभी पर होने की कोई आवश्यकता नहीं है। 3) सिफरटेक्स्ट का कोई प्रमाणीकरण नहीं है, इसलिए हमलावर इसका पता लगाए बिना ही इसमें हेरफेर कर सकते हैं (देखें: पैडिंग ऑरेकल अटैक)।
आर्टजोम बी।

है @ArtjomB डेवलपर को iv प्रबंधन के बारे में चिंता करने की आवश्यकता नहीं है क्योंकि यह एन्क्रिप्टेड स्ट्रिंग के साथ उत्पन्न और जोड़ा जाएगा।
खोपड़ी

मुझे असहमत होना पड़ेगा। चतुर्थ _ivवर्ग चर में संग्रहीत किया जाता है और सिफरटेक्स्ट में नहीं लिखा जाता है । तो, आपको कैसे लगता है कि रिसीवर को कुंजी और IV पता होगा? उन्हें किसी और तरीके से वितरित करना होगा। चूंकि IV को गुप्त नहीं माना जाता है, इसलिए इसे प्रत्येक एन्क्रिप्शन के लिए यादृच्छिक रूप से उत्पन्न किया जाना चाहिए और सिफरटेक्स्ट के साथ वितरित किया जाना चाहिए।
आर्टजोम बी।


1
1) उपरोक्त लिंक में, आप बिना एसेस को लागू करने का तरीका प्राप्त कर सकते हैं, iv प्रबंधन के बारे में चिंता करने की आवश्यकता नहीं है, क्योंकि स्ट्रिंग के साथ iv को भी एन्क्रिप्ट किया गया है। 2) क्योंकि आप जिस फ़ंक्शन को संदर्भित करते हैं, उसमें निजी एक्सेस संशोधक होता है जिसे आप बाहर से कॉल नहीं कर सकते हैं। इनक्रिप्ट एन्क्रिप्ट करने के लिए हम केवल Cryptographyclass.Encrytion ("SAMPLEstring") फ़ंक्शन का उपयोग करने में सक्षम हो सकते हैं
खोपड़ी

0

यहाँ नमूना है कि एईएस-जीसीएम एन्क्रिप्शन / डिक्रिप्शन बाउन्सी महल पैकेज का उपयोग करके कैसे किया जा सकता है।

मैंने वह नमूना पाया है जब Golang crypto/aesएपीआई से डेटा को डिक्रिप्ट करने की संभावना के लिए googled था :

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 नमूना कुंजी (256 बिट), मैक (128 बिट) और नॉन (96 बिट) के साथ एक आकर्षण की तरह काम करता है।


-1

BouncyCastle, बहुत सरल समाधान के साथ PGPCore का उपयोग करने के लिए यह अच्छा उदाहरण है : https://blog.bitscry.com/2018/07/05/pgp-enc एन्क्रिप्शन-and-dec एन्क्रिप्शन-in-c /

मैंने विभिन्न समाधानों की कोशिश की लेकिन यह मेरे लिए सबसे अच्छा काम करता है, कुछ में कीड़े हैं लेकिन यह मेरे लिए एकदम सही है।

using (PGP pgp = new PGP())
{
// Generate keys
pgp.GenerateKey(@"C:\TEMP\keys\public.asc", @"C:\TEMP\keys\private.asc", "email@email.com", "password");
// Encrypt file
pgp.EncryptFile(@"C:\TEMP\keys\content.txt", @"C:\TEMP\keys\content__encrypted.pgp", @"C:\TEMP\keys\public.asc", true, true);
// Encrypt and sign file
pgp.EncryptFileAndSign(@"C:\TEMP\keys\content.txt", @"C:\TEMP\keys\content__encrypted_signed.pgp", @"C:\TEMP\keys\public.asc", @"C:\TEMP\keys\private.asc", "password", true, true);
// Decrypt file
pgp.DecryptFile(@"C:\TEMP\keys\content__encrypted.pgp", @"C:\TEMP\keys\content__decrypted.txt", @"C:\TEMP\keys\private.asc", "password");
// Decrypt signed file
pgp.DecryptFile(@"C:\TEMP\keys\content__encrypted_signed.pgp", @"C:\TEMP\keys\content__decrypted_signed.txt", @"C:\TEMP\keys\private.asc", "password");

// Encrypt stream
using (FileStream inputFileStream = new FileStream(@"C:\TEMP\keys\content.txt", FileMode.Open))
using (Stream outputFileStream = File.Create(@"C:\TEMP\keys\content__encrypted2.pgp"))
using (Stream publicKeyStream = new FileStream(@"C:\TEMP\keys\public.asc", FileMode.Open))
    pgp.EncryptStream(inputFileStream, outputFileStream, publicKeyStream, true, true);

// Decrypt stream
using (FileStream inputFileStream = new FileStream(@"C:\TEMP\keys\content__encrypted2.pgp", FileMode.Open))
using (Stream outputFileStream = File.Create(@"C:\TEMP\keys\content__decrypted2.txt"))
using (Stream privateKeyStream = new FileStream(@"C:\TEMP\keys\private.asc", FileMode.Open))
    pgp.DecryptStream(inputFileStream, outputFileStream, privateKeyStream, "password");
}

1
Wieslaw Olborski, एक समाधान के लिए एक लिंक का स्वागत है, लेकिन कृपया सुनिश्चित करें कि आपका उत्तर इसके बिना उपयोगी है: लिंक के चारों ओर संदर्भ जोड़ें ताकि आपके साथी उपयोगकर्ताओं को कुछ पता चले कि यह क्या है और यह क्यों है, तो सबसे प्रासंगिक भाग का उद्धरण करें यदि आप लक्ष्य पृष्ठ अनुपलब्ध है, तो आप जिस पृष्ठ से लिंक कर रहे हैं, वह पृष्ठ उपलब्ध नहीं है। एक लिंक से थोड़ा अधिक उत्तर देने वाले उत्तर हटाए जा सकते हैं।
डबल-बीप

-2
            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);
                    }


                }

            }

3
वास्तव में कम गुणवत्ता। 1) ECB मोड (जिसका अर्थ है IV नहीं है) 2) 3DES 3) कुंजी और पासवर्ड को भ्रमित करता है। 4) बुरा नामकरण 5) नहीं MAC
संहिताओं में

-2

सादगी के लिए मैंने अपने लिए इस फ़ंक्शन का उपयोग किया है जो मैं गैर क्रिप्टोकरंसी प्रयोजनों के लिए उपयोग करता हूं: अपने पासवर्ड के साथ "yourpassphrase" को बदलें ...

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);
    }


}

}


4
1) कुंजी व्युत्पत्ति में कोई नमक नहीं 2) लगातार IV, जो एक IV के पूरे बिंदु को याद करता है। यह प्रत्येक एन्क्रिप्शन के लिए अलग होना चाहिए। 3) नो ऑथेंटिकेशन => पेडिंग ऑरेकल एक खतरा है 4) encryptor.TransformFinalBlockउन मेमोरी और क्रिप्टो स्ट्रीम का उपयोग करने की तुलना में सरल है।
कोडइंचाओस

-3
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;
             }
        }
    }
}

15
क्या ईसीबी सिफर मोड एक बड़ा नहीं-नहीं है?
जॉन Bubriski

4
हां, ईसीबी सबसे कम सुरक्षित विकल्प है। एमएस की टिप्पणियां देखें: "महत्वपूर्ण: यह मोड अनुशंसित नहीं है क्योंकि यह कई सुरक्षा कारनामों के लिए द्वार खोलता है।" msdn.microsoft.com/en-us/library/…
रिच

-3

मैं आपको एईएस के लिए अपने कोड के साथ अपना योगदान देना चाहता हूं Rfc2898DeriveBytes( यहां) प्रलेखन) algorhytm, C # (.NET फ्रेमवर्क 4) में लिखा है और पूरी तरह से सीमित प्लेटफार्मों के लिए भी काम कर रहा है, जैसा कि विंडोज फोन 7.0+ के लिए .NET कॉम्पैक्ट फ्रेमवर्क (सभी नहीं) प्लेटफ़ॉर्म .NET फ्रेमवर्क की हर क्रिप्टोग्राफ़िक पद्धति का समर्थन करता है!)।

मुझे आशा है कि यह किसी की मदद कर सकता है!

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;
        }
        }
    }
}

10
1) आप एक चर का उपयोग क्यों कर रहे हैं जिसे IVaआईवी नहीं, बल्कि एक पासवर्ड कहा जाता है? 2) आप IV = कुंजी क्यों सेट कर रहे हैं? आपको प्रत्येक एन्क्रिप्शन के लिए एक नया यादृच्छिक IV चाहिए। 3) मैक का अभाव ओरेकल हमलों को सक्षम बनाता है
कोडइंचोस

-4

आपको System.Security.Cryptography का उपयोग करके नामस्थान का उपयोग करना होगा; और useHashing एक बूल टाइप है, जो सच या गलत है। स्ट्रिंग "कुंजी" एन्क्रिप्शन के लिए और डिक्रिप्शन के लिए समान होना चाहिए

//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;
        }
    }

5
-1 1) ईसीबी मोड बहुत कमजोर है 2) मैक की कमी से आप सक्रिय हमलों के लिए खुले रहते हैं, जैसे कि गद्दी। 3) आप आजकल भी 3DES का उपयोग क्यों करेंगे? यह टूटा नहीं है, लेकिन एईएस स्पष्ट रूप से एक बेहतर विकल्प है।
कोडइन्चोस

-4

सुरक्षित रूप से हैश डेटा के लिए एक अच्छा एल्गोरिथ्म BCrypt है :

इंद्रधनुष तालिका के हमलों से बचाने के लिए नमक को शामिल करने के अलावा, bcrypt एक अनुकूली कार्य है: समय के साथ, इसे धीमा बनाने के लिए पुनरावृत्ति गणना को बढ़ाया जा सकता है, इसलिए यह कम्प्यूटेशन पावर बढ़ाने के साथ-साथ ब्रूट-बल खोज हमलों के लिए प्रतिरोधी बना रहता है।

BCrypt का एक अच्छा .NET कार्यान्वयन है जो एक NuGet पैकेज के रूप में भी उपलब्ध है ।


12
सवाल पूछता है कि स्ट्रिंग को एन्क्रिप्ट और डिक्रिप्ट कैसे किया जाए। जब तक मुझे कुछ भारी याद नहीं आ रहा है - आप बीसीट्रिप में स्ट्रिंग को कैसे डिक्रिप्ट कर सकते हैं? BCrypt, इसके नाम के बावजूद, एक हैशिंग फ़ंक्शन है।
१।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.