documentation icon indicating copy to clipboard operation
documentation copied to clipboard

Use secure comparison function for HMAC verification.

Open pirogoeth opened this issue 9 years ago • 1 comments

Similar to PR #196, but for other languages that need a simple, standalone, constant-time secure comparison function.


secureCompare for Ruby:

# Run a constant-time comparison against two strings to determine equality.
# Useful for performing cryptographic comparison / avoiding timing attacks.
#
# @param [String] a
# @param [String] b
# @return [Boolean]
def secureCompare(a, b)
  if a.length != b.length then
    return false
  end

  result = 0

  cmp = Hash[[a.bytes, b.bytes].transpose]
  cmp.each do |x, y|
    result |= x ^ y
  end

  return result == 0
end

secureCompare for NodeJS

var bufferEq = require('buffer-equal-constant-time');

function secureCompare(a, b) {
  bufA = new Buffer(a);
  bufB = new Buffer(b);

  return bufferEq(bufA, bufB);
}

secureCompare for PHP

<?php

function secureCompare($a, $b) {
    $bytes_a = unpack("C*", $a);
    $bytes_b = unpack("C*", $b);

    $cmplen = count($bytes_a);

    if ($cmplen !== count($bytes_b)) {
        return false;
    }

    $result = 0;

    // The result from unpack() is 1-indexed instead of 0-indexed.
    for ($i = 1; $i <= $cmplen; $i++) {
        $result |= $bytes_a[$i] ^ $bytes_b[$i];
    }

    return $result === 0;
}

?>

TODO:

  • [X] Ruby
  • [X] PHP
  • [X] Node (using buffer-equal-constant-time)
  • [x] Python (using hmac.compare_digest or standalone code..? -- done in #196 )
  • [ ] Golang (using hmac.Equal or standalone code...?)

Resources:

  • http://blog.turret.io/hmac-in-go-python-ruby-php-and-nodejs/
  • https://github.com/salesforce/buffer-equal-constant-time

pirogoeth avatar Dec 01 '16 00:12 pirogoeth

This is still an issue. Not only that, but a critical one that can compromise the security of an API token.

phayes avatar Sep 24 '19 20:09 phayes