【问题标题】:Threefish block cipher, ECB, .NET implementation: encrypted and decrypted (initial plaintext) strings' lengths are differentThreefish 分组密码、ECB、.NET 实现:加密和解密(初始明文)字符串的长度不同
【发布时间】:2014-11-20 18:25:42
【问题描述】:

我在 .NET 中加密和解密一个字符串,使用 ECB 密码模式和 Threefish 对称分组密码,我已将其实现作为 .dll Here's the link to .NET implementation附加到我的项目中

密钥大小等于块大小,在我的例子中是 256 位。

据我了解,输入字符串明文的长度必须等于密文的长度。还是必须的?例如,在我的例子中,考虑到 ASCII 编码,明文被分成块,每个块包含 32 个字符,但每个块总是有 12 个额外的密文字符,正如我已经弄清楚的那样!即密文长度=初始文本长度+12*n,其中n为文本块数,即str.Length/32(str-初始字符串,已填充为32的倍数) .

我的代码(如下)是否有错误,或者我的理解是否仅适用于非常简单的分组密码,仅使用 XOR 操作进行加密,而对于复杂的 .NET 加密系统,此规则不满足?如果是后者,请解释一下是什么让这些长度不同!!!提前谢谢你。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using SkeinFish;
using System.Security.Cryptography;
namespace ComputerSecurity_Threefish
{
    class Program
    {
        static void Main(string[] args)
        {
            string plainText = inputProperString(), decryptedText, cipherText;
            Threefish th = new Threefish();
            th.GenerateIV();
            th.GenerateKey();
            cipherText = EncryptWithThreefish(plainText, th);
            Console.WriteLine("\nThis is how your encrypted string looks like:\n" + cipherText + "\n\nNow it will be decrypted...");
            Console.WriteLine(cipherText.Length);
            decryptedText = DecryptWithThreefish(cipherText, th);
            Console.WriteLine("\nAnd here is your initial string decrypted:\n" + decryptedText);
            Console.Read();
        }
        public static string inputProperString()
        {
            Console.Write("Enter a string for encryption: ");
            string str = Console.ReadLine();
            int remainder = str.Length % 32;
            if (remainder != 0)
            {
                Console.WriteLine("\nYour string's length is not a multiple of 32, which is the equivalent of Threefish-256 blocksize for the length of ASCII string. The string will be padded with spaces.");
                for (int i = 0; i < 32 - remainder; i++)
                    str += " ";
            }
            return str;
        }
        public static string EncryptWithThreefish(string plainText, Threefish th)
        {
            MemoryStream memoryStream = new MemoryStream();

            ICryptoTransform threefishEncryptor = th.CreateEncryptor();

            CryptoStream cryptoStream = new CryptoStream(memoryStream, threefishEncryptor, CryptoStreamMode.Write);

            byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);

            cryptoStream.Write(plainBytes, 0, plainBytes.Length);

            cryptoStream.FlushFinalBlock();

            byte[] cipherBytes = memoryStream.ToArray();

            memoryStream.Close();

            cryptoStream.Close();

            return Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);
        }
        public static string DecryptWithThreefish(string cipherText, Threefish th)
        {
            MemoryStream memoryStream = new MemoryStream();

            ICryptoTransform threefishDecryptor = th.CreateDecryptor();

            CryptoStream cryptoStream = new CryptoStream(memoryStream, threefishDecryptor, CryptoStreamMode.Write);

            string decryptedText = String.Empty;

            try
            {
                byte[] cipherBytes = Convert.FromBase64String(cipherText);

                cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);

                cryptoStream.FlushFinalBlock();

                byte[] plainBytes = memoryStream.ToArray();

                decryptedText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
            }
            finally
            {
                memoryStream.Close();
                cryptoStream.Close();
            }

            return decryptedText;
        }

    }
}

【问题讨论】:

    标签: .net encryption cryptography block-cipher


    【解决方案1】:

    如果明文可被块大小整除,则如果使用 PKCS#7 填充,则为 ECB 模式加密添加完整的填充块。 Threefish 的块大小为 32、64 或 128 字节,PKCS#7 填充是 .NET 中的默认值。然而,base 64 将结果扩展了大约 1/3 加上一些可能的四舍五入,所以 12 个 base 64 字符听起来差不多。

    分组密码通常不应用明文的 XOR 进行加密。但是,流密码或使用流模式(例如 CTR)的分组密码 确实。这种加密确实需要一个 IV(或至少一个 nonce),否则如果密钥被重复使用,它会灾难性地失败。

    话虽如此,您确实不应该使用 ECB 模式加密,并且尚未完全指定 Threefish 用于加密。我建议至少 CBC 模式加密和 AES。 GCM 或 EAX 等经过身份验证的密码会更好。

    【讨论】:

    • 固定答案而不是删除它。请回复答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多