19

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

我正在寻找这三个功能

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

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

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

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

我做了很多搜索,发现了一些问题,比如EncryptOneBlock和其他人,但我正在寻找一个完整的“傻瓜”实现,我认为这对其他人也有用。

提前致谢!

4

5 回答 5

39

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

加密:

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

解密:

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(
                         toDecryptArray, 0, toDecryptArray.Length);
    //Release resources held by TripleDes Encryptor                
    tdes.Clear();
    //return the Clear decrypted TEXT
    return UTF8Encoding.UTF8.GetString(resultArray);
}
于 2012-07-10T12:48:22.203 回答
7
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>
于 2017-03-22T18:59:18.293 回答
5

为什么不使用 .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();                     
}


资料来源: MSDN

于 2012-07-10T12:52:22.697 回答
2

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

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);
            }
        }
    }
}
于 2013-12-17T21:14:06.153 回答
2

任何在 2020 年或之后阅读此主题的人都不要使用 TripleDes,因为现在它不太安全。您可以改为选择 AES(高级加密)。

您只需将 TripleDESCryptoServiceProvider 替换为 AesCryptoServiceProvider。

于 2021-06-14T15:11:14.517 回答