如何在 C# 中实现三重 DES(完整示例)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11413576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 17:47:14  来源:igfitidea点击:

How to implement Triple DES in C# (complete example)

c#asp.netencryptioncryptography

提问by James

I want to use triple DES in C# for encryption/decryption of (utf8) strings with a (utf8) key of any length.

我想在 C# 中使用三重 DES 来加密/解密带有任意长度 (utf8) 密钥的 (utf8) 字符串。

I am looking for these three functions

我正在寻找这三个功能

public static string Encrypt(string data, string key)
{
    ...
}

public static string Decrypt(string data, string key)
{
    ...
}

public static string GenerateKeyFromString(string str)
{
    ...
}

Note: Before anyone links to it, the http://www.geekzilla.co.uk/view7B360BD8-A77C-4F1F-BCA0-ACD0F6795F61.htmimplementation does not work, I have thoroughly tested it.

注意:在任何人链接到它之前,http://www.geekzilla.co.uk/view7B360BD8-A77C-4F1F-BCA0-ACD0F6795F61.htm实现不起作用,我已经对其进行了彻底的测试。

I have done lots of searching and found bits of the problem like EncryptOneBlockand others but I am looking for a complete 'for dummies' implementation which I think would be useful for others too.

我已经进行了大量搜索并发现了一些问题,例如EncryptOneBlock和其他人,但我正在寻找一个完整的“傻瓜”实现,我认为这对其他人也有用。

Thanks in advance!

提前致谢!

采纳答案by Chris Gessler

Complete source here: http://www.codeproject.com/Articles/14150/Encrypt-and-Decrypt-Data-with-C

完整来源:http: //www.codeproject.com/Articles/14150/Encrypt-and-Decrypt-Data-with-C

Encrypt:

加密:

public static string Encrypt(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 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);
}

Decrypt:

解密:

public static string Decrypt(string cipherString, bool useHashing)
{
    byte[] keyArray;
    //get the byte code of the string

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

回答by Owais Qureshi

Why not use the .Net Cryptography Library ,it has DES and Triple DES implementations. I would suggest not to reinvent the wheel and use the library ,Well if you need to practice and sharpen your skills than its great to roll out your own implementation ! :)

为什么不使用 .Net Cryptography Library,它有 DES 和 Triple DES 实现。我建议不要重新发明轮子并使用库,好吧,如果您需要练习和提高您的技能,那么推出自己的实现就更好了!:)

private static void EncryptData(String inName, String outName, byte[] tdesKey, byte[] tdesIV)
{    
//Create the file streams to handle the input and output files.
FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
FileStream fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);
fout.SetLength(0);

//Create variables to help with read and write.
byte[] bin = new byte[100]; //This is intermediate storage for the encryption.
long rdlen = 0;              //This is the total number of bytes written.
long totlen = fin.Length;    //This is the total length of the input file.
int len;                     //This is the number of bytes to be written at a time.

TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();          
CryptoStream encStream = new CryptoStream(fout, tdes.CreateEncryptor(tdesKey, tdesIV), CryptoStreamMode.Write);

Console.WriteLine("Encrypting...");

//Read from the input file, then encrypt and write to the output file.
while(rdlen < totlen)
{
    len = fin.Read(bin, 0, 100);
    encStream.Write(bin, 0, len);
    rdlen = rdlen + len;
    Console.WriteLine("{0} bytes processed", rdlen);
}

encStream.Close();                     
}


Source:MSDN


来源:MSDN

回答by TheDev6

Hereis a complete example copy paste ready..

是一个完整的示例复制粘贴准备好了..

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

namespace MVC3JavaScript_3_2012.Utilities
{
    public class MyTripleDES
    {
 private readonly TripleDESCryptoServiceProvider _des = new TripleDESCryptoServiceProvider();
        private readonly UTF8Encoding _utf8 = new UTF8Encoding();

        /// <summary>
        /// Key to use during encryption and decryption
        /// </summary>
        private byte[] _keyValue;
        public byte[] Key
        {
            get { return _keyValue; }
            private set { _keyValue = value; }
        }

        /// <summary>
        /// Initialization vector to use during encryption and decryption
        /// </summary>
        private byte[] _ivValue;
        public byte[] IV
        {
            get { return _ivValue; }
            private set { _ivValue = value; }
        }

        /// <summary>
        /// Constructor, allows the key and initialization vector to be provided as strings
        /// </summary>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        public MyTripleDES(string key, string iv)
        {
            _keyValue = Convert.FromBase64String(key);
            _ivValue = Convert.FromBase64String(iv);
        }

        /// <summary>
        /// Decrypt Bytes
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public byte[] Decrypt(byte[] bytes)
        {
            return Transform(bytes, _des.CreateDecryptor(_keyValue, _ivValue));
        }

        /// <summary>
        /// Encrypt Bytes
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public byte[] Encrypt(byte[] bytes)
        {
            return Transform(bytes, _des.CreateEncryptor(_keyValue, _ivValue));
        }

        /// <summary>
        /// Decrypt a string
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string Decrypt(string text)
        {
            byte[] input = HttpServerUtility.UrlTokenDecode(text);
            byte[] output = Transform(input, _des.CreateDecryptor(_keyValue, _ivValue));
            return _utf8.GetString(output);
        }

        /// <summary>
        /// Encrypt a string and return Base64String
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string Encrypt(string text)
        {
            byte[] input = _utf8.GetBytes(text);
            byte[] output = Transform(input, _des.CreateEncryptor(_keyValue, _ivValue));
            return HttpServerUtility.UrlTokenEncode(output);
        }

        /// <summary>
        /// Encrypt or Decrypt bytes.
        /// </summary>
        private byte[] Transform(byte[] input, ICryptoTransform cryptoTransform)
        {
            // Create the necessary streams
            using (var memory = new MemoryStream())
            {
                using (var stream = new CryptoStream(memory, cryptoTransform, CryptoStreamMode.Write))
                {
                    // Transform the bytes as requested
                    stream.Write(input, 0, input.Length);
                    stream.FlushFinalBlock();

                    // Read the memory stream and convert it back into byte array
                    memory.Position = 0;
                    var result = new byte[memory.Length];
                    memory.Read(result, 0, result.Length);

                    // Return result
                    return result;
                }
            }
        }

        public static string CreateNewVector()
        {
            using (var des = new System.Security.Cryptography.TripleDESCryptoServiceProvider())
            {
                des.GenerateIV();
                return Convert.ToBase64String(des.IV);
            }
        }

        public static string CreateNewKey()
        {
            using (var des = new System.Security.Cryptography.TripleDESCryptoServiceProvider())
            {
                des.GenerateKey();
                return Convert.ToBase64String(des.Key);
            }
        }
    }
}

回答by Godwin Awojobi

using System;
using System.Configuration;
using System.Security.Cryptography;
using System.Text;

public class TripleDESImp
{
    public static readonly string Key = ConfigurationManager.AppSettings["Encryption_Key"];
    public static readonly Encoding Encoder = Encoding.UTF8;

    public static string TripleDesEncrypt(string plainText)
    {
        var des = CreateDes(Key);
        var ct = des.CreateEncryptor();
        var input = Encoding.UTF8.GetBytes(plainText);
        var output = ct.TransformFinalBlock(input, 0, input.Length);
        return Convert.ToBase64String(output);
    }

    public static string TripleDesDecrypt(string cypherText)
    {
        var des = CreateDes(Key);
        var ct = des.CreateDecryptor();
        var input = Convert.FromBase64String(cypherText);
        var output = ct.TransformFinalBlock(input, 0, input.Length);
        return Encoding.UTF8.GetString(output);
    }

    public static TripleDES CreateDes(string key)
    {
        MD5 md5 = new MD5CryptoServiceProvider();
        TripleDES des = new TripleDESCryptoServiceProvider();
        var desKey= md5.ComputeHash(Encoding.UTF8.GetBytes(key));
        des.Key = desKey;
        des.IV = new byte[des.BlockSize / 8];
        des.Padding=PaddingMode.PKCS7;
        des.Mode=CipherMode.ECB;
        return des;
    }
}

<configuration>
<appsettings>
<add key="Encryption_Key" value="put_your_encryption_key_here"/>
</appsettings>
<configuration>