0

簡単なコード:

encodeURIComponent("\uDDBA")

結果:

URIError: URI malformed

ユーザー入力テキストとパスワードを使用する単純な暗号化を試みています。その後、そのテキストを暗号化してサーバーに保存します。

基本的に、文字「t」をエンコードしようとしています-アルゴリズムは、56762または16進数のDDBAである必要があると判断しました。

しかし、encodeURIComponent を使用してその文字をエンコードしようとすると、特定の 16 進数値がエラーになるようです。

どうすればこれを解決できますか?

私は基本的に、javascript で encodeURIComponent を適切に通過できる文字の利用可能な範囲を知る必要があります。

現在、私は次のようなことをしています:

var xor = 0xDDCE;

var plainText = "t".charCodeAt(0);
var encoded = plainText ^ xor;
var encodedChar = String.fromCharCode(encoded);
var uri = "/someuri?character=" + encodeURIComponent(encodedChar);

// This is how i would get the plain text back
var decoded = encodedChar.charCodeAt(0) ^ xor;
var decodedChar = String.fromCharCode(decoded);

これは非常に単純化されたバージョンで、xor 値は静的です。実際のケースでは、一連の変数に基づいて xor 値が計算されます。

「/someuri」は私が作成したものではなく、もともと暗号化されたデータを受信するために作成されたものではないと仮定します。単にこの URI を使用しようとしているだけです。

また、暗号化アルゴリズムを変更することもできます。xor値は、ユーザーが入力したパスワードと文字の位置を使用して、かなり単純なアルゴリズムを使用して生成されます。

これを機能させる方法の 1 つは、可能な出力文字の総数を減らし、何らかのマッピングを実行することだと考えていましたが、そのためのコードを実際に想像することはできません。

編集:

私が選択した暗号化のセキュリティに関するコメントは大歓迎です。ただし、実際のデータ セキュリティの側面はそれほど重要ではありません。「平均的な」人が出力された暗号化テキストを読めないようにしたいだけです(たくさんあると仮定してください)

4

2 に答える 2

2

普通の人にテキストを見られたくない場合は、POST リクエストまたは Base64 を使用してください。

実際のセキュリティに関しては、これはまったく役に立ちません。攻撃者は、プレーンテキストが何であるかを知る必要はありません。ユーザーがサイトに送信したものを知り、同じデータを自分自身に送り返すだけで済みます。これを防ぐ唯一の方法は、サイトのあらゆる場所で SSL を使用することです。必要に応じて、ページのソース コードにあるアルゴリズムを使用して復号化することもできます。


基本的に無料で実行できるため、JavaScript文字列がすぐに状態を検証しないのはちょっとひどいことです。Javascript 文字列は、すべてのシーケンスが有効であるとは限らないUTF-16* エンコーディングに関連付けられています。0xD800 - 0xDBFF の間の単位値を持つことは、すぐに 0xDC00 - 0xDFFF が続かない場合は無効です。また、以前のユニット値が 0xD800 - 0xDBFF でない場合、0xDC00 - 0xDFFF を持つことは無効です。

多くの場合、文字列がこれに違反する可能性があります。文字列はそれ自体を検証しないため、エラーが表示されるのはずっと後になります。

一度に 8 ビットをいつでも実行でき、それでうまくいきます。

var xor = 0xDDCE;

var input = "t",
    output = "",
    i = 0,
    ch;

while( isFinite( ch = input.charCodeAt(i++) ) {
    var xored = ch ^ xor;
    output += String.fromCharCode(
        (xored & 0xFF00) >> 8,
        xored & 0xFF
    );
}

//output is "ݺ", or 0x00DD 0x00BA, each char is always 0x00XX

※UCS-2も使える仕様ですが、見たことありません。確認したい場合:

function areStringsUTF16() {
    try {
        var str = decodeURIComponent("%F0%A0%80%80");
        return str.charCodeAt(0) === 0xd840 &&
               str.charCodeAt(1) === 0xdc00;
    }
    catch(e) {
        return false;
    }
}
于 2013-04-06T08:53:33.570 に答える
0

ごめん、

私は自分自身の質問に答えようとします

次のコードを実行します。

 (function() {
    var last = null;
    for ( var idx = 0; idx < 0xffff; idx++) {
        try {
            encodeURIComponent(String.fromCharCode(idx));
        } catch (e) {
            if (idx != last + 1) {
                console.log(idx);
            }
            last = idx;
        }
    }
    console.log(last);
 })();

その結果、

55296
57343

つまり、\uD800 と \uDFFF の間の値は許可されません。

これを書いているとき、for ループを書いてすべてをテストするべきだと思いました。

于 2013-04-06T02:29:48.967 に答える