尝试通过URI发送加密文本 - / uDDBA导致“URIError:URI格式错误”

时间:2013-04-06 02:18:27

标签: javascript unicode uri encryption-symmetric

简单代码:

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值是静态的。在实际情况中,xor值将根据一堆变量计算。

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

此外,我的加密算法可以更改。使用用户输入的密码以及角色的位置,使用相当简单的算法生成xor值。

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

编辑:

对我选择加密的安全性的评论表示赞赏;但是,实际的数据安全方面并不重要。我只是想阻止"平均"人们从能够读取输出加密文本(假设可能有很多)

2 个答案:

答案 0 :(得分:2)

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

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


Javascript字符串不会立即验证其状态,因为它可以基本上免费完成,这有点可怕。使用Javascript 字符串与UTF-16* encoding相关联,其中并非所有序列都有效。单位值介于0xD800 - 0xDBFF之间无效 当它没有立即跟随时,是0xDC00 - 0xDFFF。如果之前的单位值不是,则0xDC00 - 0xDFFF无效 0xD800 - 0xDBFF。

许多事情都可能导致字符串违反此规定,并且由于字符串不会自行验证,因此您只会在稍后看到错误。

你总是可以一次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;
    }
}

答案 1 :(得分: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循环并测试一切。