Javascript 在避免定时攻击的同时比较NodeJS缓冲区

Javascript 在避免定时攻击的同时比较NodeJS缓冲区,javascript,node.js,security,timing,Javascript,Node.js,Security,Timing,我正在用NodeJS编写一个应用程序,它使用两个Base64编码的令牌对用户进行身份验证。当XORD时,这两个令牌应该与存储在数据库中的第三个令牌匹配 这就是我现在拥有的: function verifyTokens(encodedTokens) { var similarity = 0; var buffers = encodedTokens.map(base64.decode); for (i = 0; i < TOKEN_LENGTH; i++) {

我正在用NodeJS编写一个应用程序,它使用两个Base64编码的令牌对用户进行身份验证。当XORD时,这两个令牌应该与存储在数据库中的第三个令牌匹配

这就是我现在拥有的:

function verifyTokens(encodedTokens) {
    var similarity = 0;
    var buffers = encodedTokens.map(base64.decode);
    for (i = 0; i < TOKEN_LENGTH; i++) {
        if ((buffers[0][i] ^ buffers[1][i]) === buffers[2][i]) {
            similarity += 1;
        }
    }
    return (similarity === TOKEN_LENGTH);
}
函数验证令牌(encodedTokens){
var相似性=0;
var buffers=encodedTokens.map(base64.decode);
对于(i=0;i
我认为这对于定时攻击是不安全的,因为向
相似性添加1可能比什么都不做花费更多的时间。我也不知道JavaScript相等运算符有多安全

另一个引起我注意的处理缓冲区的解决方案是,它使用
memcmp
来比较缓冲区(我知道这是不安全的)


将两个XORed缓冲区与避免定时攻击的第三个缓冲区进行比较的最佳方法是什么?我更希望在C++扩展上只使用JavaScript解决方案。

< P>你能将所有三个令牌全部XOR,和0比较吗?< /P>
var zeroes = new Buffer(Array(32)); // zero fills, not sure encoding
function verifyTokens(encodedTokens) {
  var buffers = encodedTokens.map(base64.decode);
  var xor1 = buffers[0] ^ buffers[1];
  var xor2 = xor1 ^ buffers[2];
  if(xor2.toString() === zeroes.toString()){
    // there may be a better comparison operator
    // buf1 === buf2 seems to always return false with different encodings
    return true;
  } else {
    return false;
  }
}

您可以添加生成的布尔值:

function verifyTokens(encodedTokens) {
    var buffers = encodedTokens.map(base64.decode);
    var similarity = 0;

    for (var i = 0; i < TOKEN_LENGTH; i++) {
        similarity += (buffers[0][i] ^ buffers[1][i]) === buffers[2][i]);
    }

    return similarity === TOKEN_LENGTH;
}
函数验证令牌(encodedTokens){
var buffers=encodedTokens.map(base64.decode);
var相似性=0;
对于(变量i=0;i
尽管V8可能会对此进行优化并扭曲结果。你可以自己测试一下。我首先测试
encodedTokens.map(base64.decode)

函数验证令牌(encodedTokens){
function verifyTokens(encodedTokens) {
    var similarity = 0;
    var buffers = encodedTokens.map(base64.decode);
    for (i = 0; i < TOKEN_LENGTH; i++) {
        similarity |= (buffers[0][i] ^ buffers[1][i]) | (buffers[1][i] ^ buffers[2][i]);
    }
    return similarity === 0;
}
var相似性=0; var buffers=encodedTokens.map(base64.decode); 对于(i=0;i

可能是同样的事情,但人们通常比较运算符。

不知道“比较两个XORed缓冲区的最佳方法”的答案,但您可以在返回之前花费额外的时间。这不可行吗?是的,我还计划延迟身份验证响应。我不确定它本身是否足以对抗定时攻击,即使延迟是随机的。是的,我正在想象做一些测试,以找出XOR操作需要多长时间,并添加一个setTimeout包装器,以确保函数在较长时间后返回(在这两种情况下),此外,除了问题之外,它是什么身份验证方法?与规格的链接可能会很有用(这是出于我个人的好奇心/利益)。类似的方法对我来说似乎是一个很好的改进。我应该如何测试定时攻击向量?一个简单的重复基准测试是否足够准确,还是读取源代码是唯一彻底的选择?@molf:使用基准测试。消息来源可能不会有太大帮助。