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);
}
}