0

IIS でホストされている .NET 4.0 WCF アプリケーション (basicHttpBinding) と、JavaScript RC4 アルゴリズムの実装を使用してデータを暗号化/復号化する内部クライアント アプリケーション システムとの間で、暗号化された (および base64 でエンコードされた) 文字列データを渡す必要があります。

これまでのところ、クライアントによって暗号化されたデータをサーバーに送信してからサーバーで復号化することに成功していません (またはその逆 - クライアントがサーバー応答から受信したデータを復号化する場合)。インターネット上の JavaScript ファイル (および AES) で見つかった RC4 アルゴリズムのいくつかのバリエーションを試しました。

クライアントが使用している RC4 アルゴリズムのバージョンを C# に変換しました ( https://gist.github.com/2185197にある JavaScript ファイル)。JavaScript の暗号化/復号化機能を純粋にクライアント側でテストするための html ページを作成しました。これは機能します。同様に、単体テストを通じて、c# の暗号化/復号化が .NET WCF サービス内でも機能することを確認しました。これらのテストでは、base64 エンコード/デコードはありませんでした。

C# RC4 アルゴリズムを使用すると、暗号化されたデータが base64 でエンコードされ、クライアントが .NET アプリケーションである場合 (サーバーと同じ C# アルゴリズム実装クラスを使用)、ネットワーク経由で送信されるデータの暗号化/復号化を正常に処理できます。

クライアント側の JavaScript (Firebug) および C# (Visual Studio) アルゴリズムを 1 行ずつ調べて、変数値が一致するかどうかを確認しました。コードが (Char を介して) 整数値を文字列に変換する場所を除いて、すべてが一致します。ここでの結果は矛盾しています。以下が問題の行です。

以下は、各実装のコード行です。

C#: var charX = Convert.ToChar(26).ToString();

JavaScript:

Var charX = String.fromCharCode(26);

いくつかの視覚的な違いは、単に Firebug と Visual Studio のレンダリング機能が原因である可能性があります。[私の理解では、どちらも UTF8 でエンコードされた文字列をレンダリングする必要があります]。JavaScript エンジンと JavaScript 言語のエンコーディングが異なることを読みました。そのため、Microsoft は修正 [https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode] を実装しましたが、私が実装しようとしても成功しませんでした。C# コードに実装する必要のあるエンコーディングがいくつかあるかもしれません。しかし、まだ特定されていません

上記の整数値 26 の例のように、変数値が検査されると、C# コードは左矢印を示します。JavaScript は空白を示します。JavaScript の場合、これは W3Shools (http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_fromcharcode) を介して行われたテストと一致しています。

文字処理が JavaScript と C# で一貫していることを確認するために、.NET アプリケーションで何らかのエンコーディングを実行する必要がありますか?

前もって感謝します。

以下は JavaScript コードです。

 function rc4(key, str) {
        var s = [], j = 0, x, res = '';
        for (var i = 0; i < 256; i++) {
            s[i] = i;
        }
        for (i = 0; i < 256; i++) {
            j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
            x = s[i];
            s[i] = s[j];
            s[j] = x;                
        }
        i = 0;
        j = 0;
        for (var y = 0; y < str.length; y++) {
            i = (i + 1) % 256;
            j = (j + s[i]) % 256;
            x = s[i];
            s[i] = s[j];
            s[j] = x;

            //res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);

            var sx = s[i] + s[j];
            var ssx =  s[sx % 256];
            var fromChar1 =str.charCodeAt(y);
            var fromChar2 = (fromChar1 ^ ssx);
            var fromChar3 = String.fromCharCode(fromChar2);  //******  PROBLEM LINE *******
            //var fromChar3 = fixedFromCharCode(fromChar2);                
            res += fromChar3;
        }
        return res;
    }

    //Fix as per Microsoft
    //https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode
     function fixedFromCharCode(codePt) {
        if (codePt > 0xFFFF) {
            codePt -= 0x10000;
            return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
        }
        else {
            return String.fromCharCode(codePt);
        }
    }

以下は c# コードです。

public class RC4
{
    public static string Encrypt(string key, string data)
    {
        var s = new List<int>();
        var j = 0;

        var x = 0;
        var res = string.Empty;

        for (var i = 0; i < 256; i++)
        {
            s.Add(i);
        }

        for (var i = 0; i < 256; i++)
        {
            var unicodeInt01 = ConvertedCharacterToItsUnicodeNumberic(key, i);

            j = (j + s[i] + unicodeInt01) % 256;

            x = s[i];
            s[i] = s[j];
            s[j] = x;
        }

        var f = 0;
        j = 0;
        for (var y = 0; y < data.Length; y++)
        {
            f = (f + 1) % 256;
            j = (j + s[f]) % 256;
            x = s[f];
            s[f] = s[j];
            s[j] = x;

            var unicodInt02 = ConvertedCharacterToItsUnicodeNumberic(data, y);
            var convStringOperationApplied = unicodInt02 ^ s[(s[f] + s[j]) % 256];

            var charX = Convert.ToChar(convStringOperationApplied);   //******  PROBLEM LINE *******
            var val = new string(charX, 1);
            res += val;

        }

        return res;
    }

    private static int ConvertedCharacterToItsUnicodeNumberic(string key, int i)
    {
        return key.ElementAt(i % key.Length);
    }

    public static string Decrypt(string key, string data)
    {
        return Encrypt(key, data);
    }
}
4

1 に答える 1

3

コードに送信する値に対して URL エンコードを行うだけでよいと思います。何も変更せずに実行したところ、FF と IE が 2 つの異なる値を送信していることに気付きました。したがって、値を送信する前にencodeURICompontentを使用すると、完全に機能しました。RC4 アルゴリズムに変更はありません

<script>
    $(function () {
        var value = encodeURIComponent(rc4('9F32B12B2D34FD5FB6B9F372DE67D5C38FC8BF862DB3486C52E5211589B50AB0', 'Welcome to ASP.NET MVC!'));
        $('#encrypted').val(value);
        $.get('/Home/Test?value=' + value, function (d) {
            $('#decrypted').val(d);
        });
    });
</script>
<textarea id="encrypted">
</textarea>

<textarea id="decrypted">
</textarea>

これは私がサーバー側(ASP.NET MVC)に持っているものです:

public string Test(string value)
{
    string test = RC4.Decrypt("9F32B12B2D34FD5FB6B9F372DE67D5C38FC8BF862DB3486C52E5211589B50AB0", value);

    return test;
}
于 2012-10-25T20:04:09.547 に答える