3

Rijndael アルゴリズムで暗号化された文字列を復号化しようとしています。このタイプの暗号化では、キーと IV の長さが 16 文字未満の場合、キーと IV の右側に「#」でパディングが適用されます。復号化する文字列は、それを送信する Web サービスから受信され、キーは XML SOAP 形式で送信されます。IV は、私のマシンの Mac アドレスです (サーバーが文字列を暗号化するために IV として使用します)。受信した文字列を復号化しようとすると、次の命令でプログラムがクラッシュします。

while ((num5 = stream3.ReadByte()) != -1)

そして、「パディングが無効であり、削除できません」というエラーが表示されます。MSDN でこのエラーを検索したところ、暗号化に使用された IV が復号化に使用された IV と異なる場合に発生すると言われていますが、繰り返しますが、IV は MacAddress であり、毎回同じです。

これは、Encrypt および Decrypt 関数のソースコードです。

public static string Decrypt(string strInputString, string strKeyString, string myIV)
{
        if ((strInputString == null) || (strInputString.Length == 0))
        {
            return strInputString;
        }
        try
        {
            int num5;
            int keySize = 0x100;
            int blockSize = 0x100;
            int length = keySize / 0x10;
            if (strKeyString.Length > length)
            {
                strKeyString = strKeyString.Substring(0, length);
            }
            if (strKeyString.Length < length)
            {
                strKeyString = strKeyString.PadRight(length, '#');
            }
            Encoding.Unicode.GetBytes(strKeyString);
            if (myIV.Length > length)
            {
                myIV = myIV.Substring(0, length);
            }
            if (myIV.Length < length)
            {
                myIV = myIV.PadRight(length, '#');
            }
            Encoding.Unicode.GetBytes(myIV);
            byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
            byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
            RijndaelManaged managed = new RijndaelManaged {
                BlockSize = blockSize,
                KeySize = keySize
            };
            MemoryStream stream = new MemoryStream();
            for (int i = 0; i < strInputString.Length; i += 2)
            {
                stream.WriteByte(byte.Parse(strInputString.Substring(i, 2), NumberStyles.AllowHexSpecifier));
            }
            stream.Position = 0L;
            MemoryStream stream2 = new MemoryStream();
            CryptoStream stream3 = new CryptoStream(stream, managed.CreateDecryptor(bytes, rgbIV), CryptoStreamMode.Read);
            while ((num5 = stream3.ReadByte()) != -1)
            {
                stream2.WriteByte((byte) num5);
            }
            stream3.Close();
            stream2.Close();
            stream.Close();
            byte[] buffer3 = stream2.ToArray();
            return Encoding.Unicode.GetString(buffer3);
        }
        catch (Exception exception)
        {
            Log.Error(exception.Message);
        }
}

public static string Encrypt(string strInputString, string strKeyString, string myIV)
{
        if ((strInputString == null) || (strInputString.Length == 0))
        {
            return strInputString;
        }
        try
        {
            int num4;
            int keySize = 0x100;
            int blockSize = 0x100;
            int length = keySize / 0x10;
            if (strKeyString.Length > length)
            {
                strKeyString = strKeyString.Substring(0, length);
            }
            if (strKeyString.Length < length)
            {
                strKeyString = strKeyString.PadRight(length, '#');
            }
            Encoding.Unicode.GetBytes(strKeyString);
            if (myIV.Length > length)
            {
                myIV = myIV.Substring(0, length);
            }
            if (myIV.Length < length)
            {
                myIV = myIV.PadRight(length, '#');
            }
            Encoding.Unicode.GetBytes(myIV);
            byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
            byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
            string str = "";
            RijndaelManaged managed = new RijndaelManaged {
                BlockSize = blockSize,
                KeySize = keySize
            };
            MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(strInputString));
            MemoryStream stream2 = new MemoryStream();
            CryptoStream stream3 = new CryptoStream(stream2, managed.CreateEncryptor(bytes, rgbIV), CryptoStreamMode.Write);
            while ((num4 = stream.ReadByte()) != -1)
            {
                stream3.WriteByte((byte) num4);
            }
            stream3.Close();
            stream2.Close();
            stream.Close();
            foreach (byte num5 in stream2.ToArray())
            {
                str = str + num5.ToString("X2");
            }
            return str;
        }
        catch (Exception exception)
        {
            Log.Error(exception.Message);
        }
    }

}

4

4 に答える 4

0

IVは問題ないと思います。パスワードそのものです。サーバーが暗号化に使用するパスワードは、クライアントが復号化に使用するパスワードではないと思われます。

OPが報告していたクラッシュを再現できる唯一の方法は、間違ったパスワードを Decrypt() メソッドに渡すことでした。わずかに間違った IV を渡しても、例外はスローされません。たとえば、大文字とコロンを使用して MAC アドレスとして IV を暗号化し、小文字とダッシュを使用して同じ MAC アドレスとして IV を使用して復号化しました。-- 最初の数バイトがスクランブルされましたが、約 16 バイトまでに、すべてがプレーン テキストの元のテキストと一致し始めました。

于 2012-06-05T09:09:29.247 に答える
0

パディングはおそらく Pkcs#5 です。# の代わりに、パディングするバイト数であるバイト値をパディングします。

したがって、パディングするバイトが 5 バイトの場合、パディング バイトは になり0505050505、2 バイトをパディングする必要がある場合、パディングは になります0202

于 2012-05-17T12:02:36.580 に答える
0

暗号化時に元の文字列と同じ文字エンコーディングを使用していますか?

同様の問題がありました...最終的に、違いは、暗号化するデータ(文字列)を渡す方法でした。テキストボックスにコピーして貼り付けると、プログラムにハードコーディングした場合とは暗号化が異なりました。要するに...元のデータのエンコーディングが大きな違いを生むのです。文字は同じに見えるかもしれませんが、実際にはまったく異なる表現 (8 バイト、16 バイトなど) である可能性があります。

元の文字列が暗号化アルゴリズムの前にどのようにエンコードされたかを調べます (おそらく、IV パラメーターのエンコードも確認してください。

于 2013-03-18T15:13:10.783 に答える
0

以下のテストコードで問題なく動作します-復号化のために暗号化された文字列を渡していますか?

static void Main(string[] args)
    {

        string strInputString = "test";
        string strKeyString = "test123";
        string myIV = GetMacAddress();

        string encryptedString = Encrypt(strInputString, strKeyString, myIV);
        string decryptedString = Decrypt(encryptedString, strKeyString, myIV);

    }

    public static string Decrypt(string strInputString, string strKeyString, string myIV)
    {
        if ((strInputString == null) || (strInputString.Length == 0))
        {
            return strInputString;
        }

            int num5;
            int keySize = 0x100;
            int blockSize = 0x100;
            int length = keySize / 0x10;
            if (strKeyString.Length > length)
            {
                strKeyString = strKeyString.Substring(0, length);
            }
            if (strKeyString.Length < length)
            {
                strKeyString = strKeyString.PadRight(length, '#');
            }
            Encoding.Unicode.GetBytes(strKeyString);
            if (myIV.Length > length)
            {
                myIV = myIV.Substring(0, length);
            }
            if (myIV.Length < length)
            {
                myIV = myIV.PadRight(length, '#');
            }
            Encoding.Unicode.GetBytes(myIV);
            byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
            byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
            RijndaelManaged managed = new RijndaelManaged
            {
                BlockSize = blockSize,
                KeySize = keySize
            };
            MemoryStream stream = new MemoryStream();
            for (int i = 0; i < strInputString.Length; i += 2)
            {
                stream.WriteByte(byte.Parse(strInputString.Substring(i, 2), NumberStyles.AllowHexSpecifier));
            }
            stream.Position = 0L;
            MemoryStream stream2 = new MemoryStream();
            CryptoStream stream3 = new CryptoStream(stream, managed.CreateDecryptor(bytes, rgbIV), CryptoStreamMode.Read);
            while ((num5 = stream3.ReadByte()) != -1)
            {
                stream2.WriteByte((byte)num5);
            }
            stream3.Close();
            stream2.Close();
            stream.Close();
            byte[] buffer3 = stream2.ToArray();
            return Encoding.Unicode.GetString(buffer3);

    }

    public static string Encrypt(string strInputString, string strKeyString, string myIV)
    {
        if ((strInputString == null) || (strInputString.Length == 0))
        {
            return strInputString;
        }           
            int num4;
            int keySize = 0x100;
            int blockSize = 0x100;
            int length = keySize / 0x10;
            if (strKeyString.Length > length)
            {
                strKeyString = strKeyString.Substring(0, length);
            }
            if (strKeyString.Length < length)
            {
                strKeyString = strKeyString.PadRight(length, '#');
            }
            Encoding.Unicode.GetBytes(strKeyString);
            if (myIV.Length > length)
            {
                myIV = myIV.Substring(0, length);
            }
            if (myIV.Length < length)
            {
                myIV = myIV.PadRight(length, '#');
            }
            Encoding.Unicode.GetBytes(myIV);
            byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
            byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
            string str = "";
            RijndaelManaged managed = new RijndaelManaged
            {
                BlockSize = blockSize,
                KeySize = keySize
            };
            MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(strInputString));
            MemoryStream stream2 = new MemoryStream();
            CryptoStream stream3 = new CryptoStream(stream2, managed.CreateEncryptor(bytes, rgbIV), CryptoStreamMode.Write);
            while ((num4 = stream.ReadByte()) != -1)
            {
                stream3.WriteByte((byte)num4);
            }
            stream3.Close();
            stream2.Close();
            stream.Close();
            foreach (byte num5 in stream2.ToArray())
            {
                str = str + num5.ToString("X2");
            }
            return str;

    }

    private static string GetMacAddress()
    {
        string macAddresses = "";

        foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
        {
            if (nic.OperationalStatus == OperationalStatus.Up)
            {
                macAddresses += nic.GetPhysicalAddress().ToString();
                break;
            }
        }
        return macAddresses;
    }
于 2012-05-17T08:59:09.020 に答える