簡體   English   中英

使用一種函數以最簡單的方式對字符串(而不是文件)進行解密/加密,如何實現?

[英]de-/encrypt a string (not a file) the easiest way with one function both ways possible, how?

我想在我的程序中加密一個簡短的文本框或字符串(而不是文件)來呈現其人類不可讀的內容,或者使用簡單加密來加密它是安全的(如任何敏感密碼等)。 在Visual Basic中很容易做到這五行,當我在那里復制它時,它在我的C#中不起作用。 我找不到合適的東西。 只有非常困難的例子需要大量的代碼,這些代碼主要會拋出很多錯誤,並且需要自己設置任何復雜的密鑰或密鑰對或哈希,utf編碼或兩者以使其工作而且它永遠不會。 我不知道所有這些,我只需要一個簡單的功能,它可以兼顧加密的兩種方式。 無法為C#找到類似的東西,它確實可以正常工作,並且可以向前和向后工作。 在VB中加密了C#中不存在的XOR函數。

或者我將如何獲得下面的代碼示例,它是最有希望的:如果我在button1_click事件中將其復制到C#中,它會給我帶來很多錯誤:

錯誤1:類型或名稱空間定義或預期的結束文件

錯誤2:找不到類型或命名空間“TripleDESCryptoServiceProvider”

錯誤3:當前上下文中不存在“CipherMode”

錯誤4:當前上下文中不存在“Getkey”

錯誤5:當前上下文中不存在“PaddingMode”錯誤6:錯誤8找不到類型或命名空間名稱“ICryptoTransform”(您是否缺少using指令或essemble引用?)

public static string Encrypt(string data)
{
    TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

    DES.Mode = CipherMode.ECB;
    DES.Key = GetKey("a1!B78s!5(");

    DES.Padding = PaddingMode.PKCS7;
    ICryptoTransform DESEncrypt = DES.CreateEncryptor();
    Byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(data);

    return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
}

public static string Decrypt(string data)
{
    TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

    DES.Mode = CipherMode.ECB;
    DES.Key = GetKey("a1!B78s!5(");

    DES.Padding = PaddingMode.PKCS7;
    ICryptoTransform DESEncrypt = DES.CreateDecryptor();
    Byte[] Buffer = Convert.FromBase64String(data.Replace(" ","+"));

    return Encoding.UTF8.GetString(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
}

如果您真正想要做的就是屏蔽文本輸入框的內容..在Windows窗體中,使用TextBox控件並將PasswordChar屬性設置為字符。 在WPF中,使用PasswordBox並可選擇將PasswordChar屬性設置為字符。

如果你真的需要加密,不要尋找快捷方式(自己實現,硬編碼密碼或密鑰),因為你最終會看到一些看起來很安全的東西,但是真的可以在幾分鍾內被知道自己在做什么的人攻擊。

在這里,您的方法現在將如下工作:

public static string Encrypt(string data)
{
    using (var des = new TripleDESCryptoServiceProvider { Mode = CipherMode.ECB, Key = GetKey("a1!B78s!5(j$S1c%"), Padding = PaddingMode.PKCS7 })
    using (var desEncrypt = des.CreateEncryptor())
    {
        var buffer = Encoding.UTF8.GetBytes(data);

        return Convert.ToBase64String(desEncrypt.TransformFinalBlock(buffer, 0, buffer.Length));
    }
}

public static string Decrypt(string data)
{
    using (var des = new TripleDESCryptoServiceProvider { Mode = CipherMode.ECB, Key = GetKey("a1!B78s!5(j$S1c%"), Padding = PaddingMode.PKCS7 })
    using (var desEncrypt = des.CreateDecryptor())
    {
        var buffer = Convert.FromBase64String(data.Replace(" ", "+"));

        return Encoding.UTF8.GetString(desEncrypt.TransformFinalBlock(buffer, 0, buffer.Length));
    }
}

問題是A)密鑰長度無效(我猜是由於缺少GetKey()定義 - 但是每個字符16個字符乘以8位是Triple DES的最小128位)和B)獲取源字符串的字節為ASCII用於加密,但在解密后,使用UTF8編碼。

除了我在鏈接問題中的答案,你可以做類似的事情,

public static string Obfuscate(string before)
{
    var beforeArray = Encoding.Unicode.GetBytes(before);
    var count = beforeArray.Length;
    var resultArray = new byte[count];
    var o = count % 32;

    for (var i = 0; i < count; i++)
    {
       var xor = o + 32;
       resultArray[i] = (byte)(beforeArray[i] ^ xor);
       o = ++o % 32;
    }

    return Encoding.Unicode.GetString(resultArray)
}

它是字符串中字節的一個微不足道的XOR。 它不是加密,但它使字符串很難讓人閱讀。

如果你真的想要強加密,你必須從避開TDES開始。

補充了Jesse C. Slicer接受的答案,這里是“GetKey”代碼,我在這里找到了它

  private static byte[] GetKey(string password)
  {
     string pwd = null;

     if (Encoding.UTF8.GetByteCount(password) < 24)
     {
         pwd = password.PadRight(24, ' ');
     }
     else
     {
         pwd = password.Substring(0, 24);
     }
     return Encoding.UTF8.GetBytes(pwd);
  }

更好的是......使用AES而不是3DES。 有關為什么你可以在另一個SO答案中看到這里的解釋

以下是我使用的一些加密/解密方法。 輸入和輸出是base64Strings。

static string EncryptStringToBase64String(string plainText, byte[] Key, byte[] IV)
{
    // Check arguments. 
    if (plainText == null || plainText.Length <= 0)
        throw new ArgumentNullException("plainText");
    if (Key == null || Key.Length <= 0)
        throw new ArgumentNullException("Key");
    if (IV == null || IV.Length <= 0)
        throw new ArgumentNullException("Key");
    byte[] encrypted;
    // Create an RijndaelManaged object 
    // with the specified key and IV. 
    using (RijndaelManaged rijAlg = new RijndaelManaged())
    {
        rijAlg.Key = Key;
        rijAlg.IV = IV;

        // Create a decrytor to perform the stream transform.
        ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

        // Create the streams used for encryption. 
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    //Write all data to the stream.
                    swEncrypt.Write(plainText);
                }
                encrypted = msEncrypt.ToArray();
            }
        }
    }

    // return encrypted bytes converted to Base64String
    return Convert.ToBase64String(encrypted);
}

static string DecryptStringFromBase64String(string cipherText, byte[] Key, byte[] IV)
{
    // Check arguments. 
    if (cipherText == null || cipherText.Length <= 0)
        throw new ArgumentNullException("cipherText");
    if (Key == null || Key.Length <= 0)
        throw new ArgumentNullException("Key");
    if (IV == null || IV.Length <= 0)
        throw new ArgumentNullException("Key");

    // Declare the string used to hold 
    // the decrypted text. 
    string plaintext = null;

    // Create an RijndaelManaged object 
    // with the specified key and IV. 
    using (RijndaelManaged rijAlg = new RijndaelManaged())
    {
        rijAlg.Key = Key;
        rijAlg.IV = IV;

        // Create a decrytor to perform the stream transform.
        ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

        // Create the streams used for decryption. 
        using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText)))
        {
            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();
                }
            }
        }
    }

    return plaintext;
}

這是一些測試代碼,因為我看到你在加密/解密中創建你的Key / IV。

    var inputString = "SomeText";
    var r = RijndaelManaged.Create();
    r.GenerateKey();
    r.GenerateIV();
    var key = r.Key;
    var iv = r.IV;

    var a = EncryptStringToBase64String(inputString, key, iv);
    var b = DecryptStringFromBase64String(a, key, iv);
    Assert.AreEqual(b, inputString);
    Assert.AreNotEqual(a, inputString);

使用System.Security.Cryptography; ;

public class StringCipher
{

    private const int keysize = 256;

    public static string Encrypt(string plainText)
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes("123", null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            byte[] cipherTextBytes = memoryStream.ToArray();
                            return Convert.ToBase64String(cipherTextBytes);
                        }
                    }
                }
            }
        }
    }

    public static string Decrypt(string cipherText)
    {
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes("123", null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                        }
                    }
                }
            }
        }
    }
}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM