0

ECB 暗号モードと Threefish 対称ブロック暗号を使用して、.NET で文字列を暗号化および復号化しています。その実装は、プロジェクトに .dll として添付されています。.NET 実装へのリンクは次のとおりです。

キーのサイズはブロック サイズと同じで、私の場合は 256 ビットです。

問題は、私が理解している限り、入力文字列、平文の長さは暗号文の長さと等しくなければならないということです。それともしなければなりませんか?たとえば、私の場合、ASCII エンコーディングを考慮すると、平文は各ブロックに 32 文字を含むブロックに分割されますが、各ブロックには常に 12 文字の暗号文が追加されていることがわかりました。つまり、暗号文の長さ = 最初のテキストの長さ + 12*n、ここで n はテキストのブロック数、つまり str.Length/32 (str - 最初の文字列、32 の倍数になるように既にパディングされています) .

私のコード (以下) にエラーがありますか、または複雑な .NET 暗号化システムではこのルールが満たされないのに対し、暗号化に XOR 操作のみを使用する非常に単純なブロック暗号の場合にのみ私の理解は有効ですか? 後者の場合は、実際にこれらの長さが異なる理由を説明してください!!! 前もって感謝します。

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

    }
}
4

1 に答える 1

0

平文がブロック サイズで割り切れる場合、PKCS#7 パディングが使用されている場合、ECB モード暗号化のためにパディングの完全なブロックが追加されます。Threefish のブロック サイズは 32、64、または 128 バイトで、PKCS#7 パディングが .NET のデフォルトです。ただし、基数 64 は結果を約 1/3 プラスいくらかの切り上げで拡張するため、12 個の基数 64 文字はほぼ正しいように聞こえます。

通常、ブロック暗号は暗号化に平文の XOR を適用しません。ただし、ストリーム暗号、または CTR などのストリーミング モードを使用するブロック暗号はそうです。その種の暗号化には IV (または少なくともノンス) が必要です。そうしないと、鍵が再利用されると壊滅的に失敗します。

とはいえ、ECB モードの暗号化を使用するべきではなく、Threefish では暗号化が完全に指定されていません。少なくとも CBC モードの暗号化と AES をお勧めします。GCM や EAX などの認証された暗号はさらに優れています。

于 2014-11-16T20:05:18.963 に答える