2016-04-27 8 views
1

Ich versuche die Funktion createHmac von nodejs aus seiner Crypto-Bibliothek zu verwenden.nodejs crypto hmac erzeugt verschiedene Hashes, wenn secret als Literal vs Variable übergeben wird

Problem: Es erzeugt verschiedene Hashes, wenn (scheinbar) identische Argumente gegeben. Der einzige Unterschied ist, ob der Parameter 'secret' eine String-Variable oder ein String-Literal ist.

Das folgende SPA isoliert das Problem. Ich benutze nwjs (node ​​webkit) SDK Flavor v 0.14.2, um diesen Code auf OS X El Cap auszuführen.

Alle Hilfe und Beratung dankbar erhalten.

index.html

<!DOCTYPE html> 
<html> 
<head> 
    <title>Context Menu</title> 
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" 
    rel="stylesheet" 
    integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" 
    crossorigin="anonymous"> 
</head> 
<body style="width: 100%; height: 100%;"> 

<div id="wrapper"> 
</div> 

<script src="https://code.jquery.com/jquery-2.2.3.min.js" 
    integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=" 
    crossorigin="anonymous"></script> 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" 
    integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" 
    crossorigin="anonymous"></script> 
<script type="text/javascript" src="./index.js"></script> 
</body> 
</html> 

index.js

var nodeCrypto = require('crypto'); 

var payload = 'twas brillig and the slithy toves did gyre and gimble in the wabe'; 

// 
// simple UI to get a user-entered secret 
// and echo the results. 
// enter 'wibble' in input element to demo the problem to match hard coded literal 
// 
$('#wrapper').append (
    $('<div>').addClass('form-group') 
     .append (
      $('<label>').attr('for','userinput').text('Tell me a secret:'), 
      $('<input>').addClass('form-control').attr('type','text').attr('id','userinput') 
     ), 
    $('<p>').attr('id', 'hash'), 
    $('<p>').attr('id', 'nash') 
); 

$('input').on('change', function (ev) { 

    // compute hash based on user input 
    var hash = nodeCrypto.createHmac ('sha256', $(this).val()) 
     .update (payload) 
     .digest ('hex');    
    console.log ('hash: ' + hash); 
    $('p[id=hash]').text('secret: ' + $(this).val() + ', hash: ' + hash); 
    // logs hash: f7b4ae1aaa35b813571f00bca7c81d08176b56cb3a1d1f8c8ba95a17ba6f6f29 
    // as long as user enters 'wibble' 

    // compute hash based on string literal 
    var nash = nodeCrypto.createHmac ('sha256', 'wibble') 
       .update (payload) 
       .digest ('hex');    
    console.log ('nash: ' + nash); 
    $('p[id=nash]').text('secret: wibble, hash: ' + nash); 
    // logs hash: c9592948b3de038c9aa339f94b61928de803417183a6c95b1829a04c69fe6bf6 

}); 

Screen Shows user input together with computed hashes

package.json

{ 
    "name": "hmac", 
    "main": "index.html", 
    "description": "nodejs crypto hmac test", 
    "author": "xxx" 
} 

Antwort

1

Es gibt etwas über die Disziplin ein Problem zu isolieren und eine Erklärung für das harte, aber faires Publikum zu schreiben, die Stackoverflow ist, die oft eine Lösung wie von selbst zu schütteln scheint.

Also mit Entschuldigungen für diese 'fragte & beantwortet'. Ich bin nur erleichtert, eine Lösung zu haben.

Ein wenig weitere Experimente ergaben diese Erkenntnisse:

  1. das Argument zwingt Inneren Krypto Bibliothek von Knoten über

secret = new String(...)

verursacht einen Ausfall ein separates Objekt zu sein:

TypeError: not a buffer.

Dies ist ein Hinweis!

  1. nach dem Konvertieren der Benutzereingabe in einen Puffer, bevor es als das Geheimnis zu CreateHmac führt führt zu konsistentem Verhalten zwischen den 2 Aufrufen.

Aktualisiert js

// compute hash based on user input 
    var secretStr = $(this).val(); 
    var hash = nodeCrypto.createHmac ('sha256', secretStr) 
     .update (payload) 
     .digest ('hex');    
    console.log ('hash: ' + hash); 
    $('p[id=hash]').text('secret: ' + $(this).val() + ', hash: ' + hash); 
    // logs hash: f7b4ae1aaa35b813571f00bca7c81d08176b56cb3a1d1f8c8ba95a17ba6f6f29 
    // as long as user enters 'wibble' 

    // compute hash based on string literal 
    var nash = nodeCrypto.createHmac ('sha256', 'wibble') 
     .update (payload) 
     .digest ('hex');    
    console.log ('nash: ' + nash); 
    $('p[id=nash]').text('secret: wibble, nash: ' + nash); 
    // logs nash: c9592948b3de038c9aa339f94b61928de803417183a6c95b1829a04c69fe6bf6 

    // compute hash based on Buffer initialised from user input 
    var secretBuf = Buffer.from($(this).val()); 
    var mash = nodeCrypto.createHmac ('sha256', secretBuf) 
     .update (payload) 
     .digest ('hex');    
    console.log ('nash: ' + nash); 
    $('p[id=mash]').text('secret: wibble, mash: ' + nash); 
    // logs mash: c9592948b3de038c9aa339f94b61928de803417183a6c95b1829a04c69fe6bf6 
Verwandte Themen