0

私はこの暗号化と復号化の技術に不慣れです。

私は Clickbankインスタント通知システムのタスクに取り組んでいます。Clickbank から暗号化された値を取得しており、通知を解読したいと考えています。私の問題はこのスレッドと非常に似ていますが、うまくいきません。次のエラーがスローされます。

指定された初期化ベクトル (IV) が、このアルゴリズムのブロック サイズと一致しません。

以下は、復号化のための私のコードです。

protected void Page_Load(object sender, EventArgs e)
{
    //Sample response
    string sContent = "{\"notification\":\"18XR9s5fwkbhvfriqYS6jDJERf++jshcTDQX4NuUoUHtS+YzfMCNiEvmIVNxkbT5My2xWLFPB9mb\nEjwpHd3A6b9WJDYiXc0nufTxhXDAL1JzyYryEZAq7Bogj7mHjxUfFhc419wDmQteoSEz4H0IsKha\nIoxSfA5znd6WZKCSY9Dxx0wbZ8jLNL8SOYxi7pbFdKgMgKULKEh4EPKaWAvhE5UjWtzuHvMX37NI\nOvApkBoYEDE2mrde/SjLigE38X2wsGB4M6pYVkfzEE6rbYfVNxadkNHmri1xlaa+Grudy6vt6wzq\nPUfroEb6uRlxj2e6dmKZE4kynJFmRosMJ4ZRC+sYW+DyvkbdSY2dl1ZMNPhP+yhcMkbU8HQKUipw\nd7FUpb6utfiDB8YL5z7pJMnjHP01PsIvG+eSj0Lfj1gmbtVJt6TOJ4BCZxZdfdPRlJtPdOUiMRRk\nQ3Wn5g9VuvzNYg2ostZ+/HE778M6lZ264KbpMZSqEj4cTPCGFFNt7VCz9fXVoDLa7oI7KGY6rgxb\nBLWXdX058RSd0gSzC8otkCx9b6p8FZ5XxAX4qbU814batcbxw3V3GGVf97VLSVysdrHc+PEFdocl\nqaRarCHG5e2ZpEgQLoCtRhA99qkuS9Uc9+Hm1KT4kD2HIrPSclJWzUMoKuAG4n95EG0Q5ca0WZQx\naLNhdPyJmSLNwjV/SNPxYdyy81ENZtLbwJOYENCnpd41z73HF91/R1hrxQ0rCZsb6BBRGUeowEzE\nSKPSbWjDCQ6hLZTjObsOt6eTAmn8TrzjyqdwUfxHhLEtIQIOr4gPXxXqwGHYcNkRFezkwMScl2Hr\nmJ+Zm1xCqs9+fOOiO6TtZYKS+9Dl/JevMfGdbcPw8/5F7+ZVAkCcDS8OGaVv\",\"iv\":\"NDVEM0M4ODZGMzE4OTVENA==\"}";


    using (var reader = new StreamReader(Request.InputStream))
    {
        //Using below two lines for live testing
        //JavaScriptSerializer js = new JavaScriptSerializer();
        //sContent = reader.ReadToEnd();

        JObject jObject = JObject.Parse(sContent);

        JToken notification = jObject["notification"];
        JToken i = jObject["iv"];


        using (StreamWriter _testData = new StreamWriter(Server.MapPath("~/data.txt"), true))
        {
            _testData.WriteLine("=======================Notification"); // Write the file. 
            _testData.WriteLine(notification.ToString());
            _testData.WriteLine("=======================IV"); // Write the file. 
            _testData.WriteLine(i.ToString());

            string n = notification.ToString();
            string v = i.ToString();

            string sk = "MY SECRET KEY";


            byte[] key = Encoding.UTF8.GetBytes(sk);
            byte[] iv = Encoding.UTF8.GetBytes(v);

            try
            {
                using (var rijndaelManaged =
                       new RijndaelManaged { Key = key, IV = iv, Mode = CipherMode.CBC })
                using (var memoryStream =
                       new MemoryStream(Convert.FromBase64String(n)))
                using (var cryptoStream =
                       new CryptoStream(memoryStream,
                           rijndaelManaged.CreateDecryptor(key, iv),
                           CryptoStreamMode.Read))
                {
                    var dString = new StreamReader(cryptoStream).ReadToEnd();
                }
            }
            catch (CryptographicException ex)
            {
                Console.WriteLine("A Cryptographic error occurred: {0}", ex.Message);

            }
        }
    }
}

どこが間違っているのか教えてください。

ありがとう

4

2 に答える 2

1

このまったく同じ問題に頭をぶつけたところなので、ここに私の解決策があります。心に留めておくべきことは、パスフレーズ/秘密鍵が sha1 によってハッシュされ、最初の 32 個の 16 進数文字がキー バイトとして使用されることです。私を悩ませていた部分は、文字がc#のUFT16文字であり、実際にはそれぞれ2バイトでしたが、ソース暗号化が使用したものではありませんでした. だから私がしたことは、文字列を正しいバイト配列を持つASCII文字列に変換することでした。最もクリーンなコードではありませんが、機能的です。

    public static string DecryptClickBankNotification(string cipherText, string passPhrase, string initVector)
    {
        string decryptedString = null;

        byte[] inputBytes = Encoding.UTF8.GetBytes(passPhrase);

        SHA1 sha1 = SHA1.Create();
        byte[] key = sha1.ComputeHash(inputBytes);

        StringBuilder hex = new StringBuilder(key.Length * 2);
        foreach (byte b in key)
            hex.AppendFormat("{0:x2}", b);

        string secondPhaseKey = hex.ToString().Substring(0,32);

        ASCIIEncoding asciiEncoding = new ASCIIEncoding();

        byte[] keyBytes = asciiEncoding.GetBytes(secondPhaseKey);
        byte[] iv = Convert.FromBase64String(initVector);

        try
        {
            using (RijndaelManaged rijndaelManaged = new RijndaelManaged
            { 
                Key = keyBytes,
                IV = iv,
                Mode = CipherMode.CBC, 
                Padding = PaddingMode.PKCS7})
                using (Stream memoryStream = new MemoryStream(Convert.FromBase64String(cipherText)))
                using (CryptoStream cryptoStream =
                   new CryptoStream(memoryStream,
                       rijndaelManaged.CreateDecryptor(keyBytes, iv),
                       CryptoStreamMode.Read))
            {
                decryptedString = new StreamReader(cryptoStream).ReadToEnd();
            }
        }
        catch (Exception ex)
        {
            Trace.WriteLine(new TraceData(TraceCategoryEnum.Errors, "Error decrypting message: " + ex.Message));
        }

        return decryptedString;
    }
于 2016-04-28T01:53:27.883 に答える
0

v が 16文字Encoding.UTF8.GetBytes(v);、バイト数が 16 から 64 の間である場合、エラーが発生する可能性があります。

指定された初期化ベクトル (IV) が、このアルゴリズムのブロック サイズと一致しません。

iv が 16 バイトであることを確認します。

于 2015-03-24T17:50:13.220 に答える