0

简单代码:

encodeURIComponent("\uDDBA")

结果:

URIError: URI malformed

我正在尝试做一个简单的加密,它将接受一些用户输入的文本和密码,然后它将加密该文本并将其保存到服务器。

基本上我正在尝试编码一个字母“t” - 并且算法已经确定应该是 56762 或 DDBA 十六进制。

但是,如果我尝试使用 encodeURIComponent 对该字符进行编码,那么某些十六进制值似乎会导致错误。

我该如何解决这个问题?

我基本上需要知道可以正确通过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 值将基于一堆变量来计算。

假设“/someuri”不是由我构建的,并且最初并不是为了接收加密数据而构建的,我只是想使用这个 URI。

此外,我的加密算法可以更改。该xor值将使用一个相当简单的算法生成,该算法使用用户输入的密码和字符的位置。

我正在考虑使这项工作的一种方法是减少可能的输出字符的总数并执行某种映射......但我无法真正想象代码。

编辑:

感谢您对我选择的加密的安全性发表评论;然而,实际的数据安全方面并不那么重要。我只是想防止“普通”人能够阅读输出的加密文本(假设可能有很多)

4

2 回答 2

2

如果您不希望普通人看到文本,只需使用 POST 请求或 Base64。

至于实际的安全性,这完全没用。攻击者不需要知道明文是什么,他只需要知道用户发送到您的站点的内容并自己发回相同的数据即可。防止这种情况的唯一方法是在您网站的任何地方都使用 SSL。如果他们愿意,他们可以使用您在页面源代码中找到的算法来解密它。


Javascript 字符串不能立即验证它们的状态有点可怕,因为它基本上可以免费完成。Javascript 字符串与并非所有序列都有效的UTF-16* 编码相关联。当没有立即跟随为 0xDC00 - 0xDFFF 时,在 0xD800 - 0xDBFF 之间的单位值是无效的。如果先前的单位值不是 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 回答