0

Webアプリケーションで保護されたデータの暗号化と復号化に「AesManaged」を使用しています。私のシナリオでは、ユーザーがログインしたときに「Email + CurrentDate」に基づいてトークンを作成し、暗号化された形式でユーザーに送り返します(暗号化はAESManagedクラスを使用して行われます)。また、ユーザーが次のサーバー側のメソッドを呼び出すと、たとえば「 「レポートを表示」の場合、ユーザー/クライアントアプリケーションは、その暗号化されたトークンをリクエストとともに送信します。サーバー側でトークンを復号化し、復号化されたトークンに基づいて条件付きロジックを実行した後、特定のユーザーがこのメソッドにアクセスできるかどうかが決定されます(一種の認証チェック)。

サーバーから取得した正しい暗号化文字列をユーザーが提供するか、同じ長さであるがユーザーが暗号化文字列の文字を置き換えるという基本的なフローでは、(期待どおりに)正常に動作しています。

ただし、ユーザーが(たとえば)54文字の文字列を取得したが、サーバーに7文字しか送信しない場合、問題が発生します。その後、次の例外が発生します。

ユーザーが無効なデータを提供した場合でも、この例外を回避したいと思います。したがって、基本的に文字列は常に復号化する必要があり、それが無効なトークンである場合は、リソースへのアクセスを制限できます。どうすればこれを達成できますか?あなたの答えは高く評価されます。

例外の詳細:

例外が発生する特定のコードブロック。

 // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

例外:「復号化するデータの長さが無効です。」

例外の詳細:

ターゲットサイト:{Byte [] TransformFinalBlock(Byte []、Int32、Int32)}

タイプの宣言:{Name = "RijndaelManagedTransform" FullName = "System.Security.Cryptography.RijndaelManagedTransform"}

名前: TransformFinalBlock

注:暗号化と復号化の両方の方法で同じキーとivを提供しています。

コード:

public string EncryptAuthenticationTokenAes(string plainText, byte[] Key, byte[] IV)
        {


            byte[] encrypted;
            // Create an AesManaged object
            // with the specified key and IV.
            using (AesManaged aesAlg = new AesManaged())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;


                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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 the encrypted bytes from the memory stream.
            return Convert.ToBase64String(encrypted);

        }

        public string DecryptPasswordAes(string encryptedString, byte[] Key, byte[] IV)
        {
            // becuase it is base64, if mod4>0 then it is consider as invalid token
            int mod4 = encryptedString.Length % 4;
            if (mod4 > 0)
            {
                return string.Empty;
            }
            byte[] cipherText = Convert.FromBase64String(encryptedString);
            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;

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

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

                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

            }

            return plaintext;
        }
4

3 に答える 3

1

これらの 7 文字を取得して意味のある変換を実行する方法がないことを示しています。それらを使用していかなる種類の復号化も実行できません。

復号化を試みる前に長さチェックを実行するか、例外をキャッチします。どちらの場合も、「無効なトークンが受信されました」というロジックのルートをたどってください。

于 2012-05-14T06:41:41.550 に答える
0

これを試して

           // Create the streams used for decryption.
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        if (encryptedString.Length != aesAlg.BlockSize)
                        {
                            // Handle invalid token here.
                        }
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
于 2012-05-14T07:11:27.073 に答える
0

暗号化された文字列の長さを保存し、長さが同じかどうかを確認します。はいの場合は、復号化メソッドの呼び出しに進みます。

于 2012-05-27T10:49:28.943 に答える