2

暗号化の問題について報告するために書いています。RijndaelManagedのクラスを使用すると問題が発生しSystem.Security.Cryptographyます。RijndaelManagedパディングなしでCFB-8(FeedbackSize = 8) モードで使用することが重要です( PaddingMode.None)。このような設定により、暗号化されたデータのサイズと復号化されたデータのサイズが等しくなります。

残念ながら、Mono (MVS2010 IDE v2.0.8152 用の Mono コンパイラ) でコンパイルされたコードは、データ暗号化で例外をスローし、次のメッセージが表示されます。

[Unhandled Exception: System.Security.Cryptography.CryptographicException: invalid block length at Mono.Security.Cryptography.SymmetricTransform.FinalEncrypt]. 

ネイティブの Visual Studio 2010 コンパイラを使用して、Windows XP および Windows 7 で .NET Framework 4.0 をテストしました。ネイティブの Microsoft .NET コンパイラは例外をスローせず、コード例はうまく機能することがわかりました。

以下に 2 つの例 (Repro コード) を貼り付けました。1 つは例外をスローする Mono 用で、もう 1 つはネイティブ C# コンパイラ用で、この場合例外はありません。また、コードをテストするためのオンライン コンパイラへのリンクも貼り付けました。

Mono コンパイラがこの例外をスローするのはなぜですか?


Mono コード サンプル (テスト用オンライン コンパイラ、Compile Online )

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace Dela.Mono.Examples
{
   public class HelloWorld
   {
      public static void Main(string[] args)
      {
         string plainText = "This will be encrypted.";
            string plainText2 = "";

            RijndaelManaged aesAlg = new RijndaelManaged();

            aesAlg.BlockSize = 128;
            aesAlg.KeySize = 256;
            aesAlg.Mode = CipherMode.CFB;
            aesAlg.FeedbackSize = 8;
            aesAlg.Padding = PaddingMode.None;

            aesAlg.GenerateKey();
            aesAlg.GenerateIV();

            ICryptoTransform encryptor = aesAlg.CreateEncryptor();

            MemoryStream msEncrypt = new MemoryStream();
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) {
                    swEncrypt.Write(plainText);
                }
            }

            Console.WriteLine(msEncrypt.ToArray().Length); 
            Console.WriteLine(System.Text.Encoding.UTF8.GetString(msEncrypt.ToArray()));

            byte[] customArray = msEncrypt.ToArray();

            ICryptoTransform decryptor = aesAlg.CreateDecryptor();

            MemoryStream msDecrypt = new MemoryStream(customArray);
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) {
                using (StreamReader swDecrypt = new StreamReader(csDecrypt)) {
                    plainText2 = swDecrypt.ReadToEnd();
                }
            }

            Console.WriteLine(plainText2.Length); 
            Console.WriteLine(plainText2);


      }
   } 
}

ネイティブ C# コード サンプル (テスト用オンライン コンパイラ、Compile Online )

// Rextester.Program.Main is the entry point for your code. Don't change it.

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string plainText = "This will be encrypted.";
            string plainText2 = "";

            RijndaelManaged aesAlg = new RijndaelManaged();

            aesAlg.BlockSize = 128;
            aesAlg.KeySize = 256;
            aesAlg.Mode = CipherMode.CFB;
            aesAlg.FeedbackSize = 8;
            aesAlg.Padding = PaddingMode.None;

            aesAlg.GenerateKey();
            aesAlg.GenerateIV();

            ICryptoTransform encryptor = aesAlg.CreateEncryptor();

            MemoryStream msEncrypt = new MemoryStream();
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) {
                    swEncrypt.Write(plainText);
                }
            }

            Console.WriteLine(msEncrypt.ToArray().Length); 
            Console.WriteLine(System.Text.Encoding.UTF8.GetString(msEncrypt.ToArray()));

            byte[] customArray = msEncrypt.ToArray();

            ICryptoTransform decryptor = aesAlg.CreateDecryptor();

            MemoryStream msDecrypt = new MemoryStream(customArray);
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) {
                using (StreamReader swDecrypt = new StreamReader(csDecrypt)) {
                    plainText2 = swDecrypt.ReadToEnd();
                }
            }

            Console.WriteLine(plainText2.Length); 
            Console.WriteLine(plainText2);
        }
    }
}

4

1 に答える 1

2

バグが修正されました。ソースは mono GIT リポジトリから取得できます。

マスター: e094d3dc0cf186f1de32d5340d847dc18aeca0e2

mono-2-10: 98e4842eb19dfd60000ada19e9bfb265fad7c84b

于 2012-11-19T09:06:04.073 に答える