2016-07-20 2 views
0

아래는 multipassify의 출처입니다.Node.js v6.2.2 crypto.createCipheriv "유효하지 않은 키 길이"오류

코드는 노드 6 아래에서 완벽하게 작동하며 이후에는 오류가 발생합니다.

오류는 다음과 같습니다

crypto.js:184 
    this._handle.initiv(cipher, toBuf(key), toBuf(iv)); 
      ^

Error: Invalid key length 
    at Error (native) 
    at new Cipheriv (crypto.js:184:16) 
    at Object.Cipheriv (crypto.js:182:12) 
    at multipassify.encrypt (/Users/thomasreggi/Desktop/super-octopus/node_modules/multipassify/multipassify.js:52:25) 
    at multipassify.encode (/Users/thomasreggi/Desktop/super-octopus/node_modules/multipassify/multipassify.js:28:27) 
    at Object.<anonymous> (/Users/thomasreggi/Desktop/super-octopus/multi.js:8:26) 
    at Module._compile (module.js:541:32) 
    at Object.Module._extensions..js (module.js:550:10) 
    at Module.load (module.js:458:32) 
    at tryModuleLoad (module.js:417:12) 

여기 소스입니다.

var crypto = require('crypto'); 

var BLOCK_SIZE = 16; 

var multipassify = module.exports = function(secret) { 
    if (!(this instanceof multipassify)) return new multipassify(secret); 
    if (!(typeof secret == 'string' && secret.length > 0)) throw new Error('Invalid Secret'); 

    // Use the Multipass secret to derive two cryptographic keys, 
    // one for encryption, one for signing 
    var hash = crypto.createHash("sha256").update(secret).digest('binary'); 
    this._encryptionKey = hash.substring(0, BLOCK_SIZE); 
    this._signingKey = hash.substring(BLOCK_SIZE, 32); 
    return this; 
}; 

multipassify.prototype.encode = function(obj) { 
    if (!obj) return; 

    // Store the current time in ISO8601 format. 
    // The token will only be valid for a small timeframe around this timestamp. 
    obj["created_at"] = new Date().toISOString(); 

    // Serialize the customer data to JSON and encrypt it 
    var cipherText = this.encrypt(JSON.stringify(obj)); 

    // Create a signature (message authentication code) of the ciphertext 
    // and encode everything using URL-safe Base64 (RFC 4648) 
    var token = new Buffer(cipherText + this.sign(cipherText),'binary').toString('base64'); 
    token = token.replace(/\+/g, '-') // Replace + with - 
     .replace(/\//g, '_'); // Replace/with _ 

    return token; 
}; 

multipassify.prototype.generateUrl = function(obj, domain) { 
    if(!domain) return; 
    return "https://" + domain + "/account/login/multipass/" + this.encode(obj); 
}; 

multipassify.prototype.sign = function (data) { 
    var signed = crypto.createHmac("SHA256", this._signingKey).update(data).digest('binary'); 
    return signed; 
} 

multipassify.prototype.encrypt = function(plaintext) { 
    // Use a random IV 
    var iv = crypto.randomBytes(BLOCK_SIZE); 
    var cipher = crypto.createCipheriv('aes-128-cbc', this._encryptionKey,iv); 

    // Use IV as first block of ciphertext 
    var encrypted = iv.toString('binary') + cipher.update(plaintext, 'utf8', 'binary') + cipher.final('binary'); 
    return encrypted; 
} 

내가 이진 해시 및 this._encryptionKey 변환과 장난 시도했습니다. 이 github issue 가이드로 사용하지만 노드 6 작동하도록 얻으려고 운이 필요가 있습니다. 누구나 쉽게 노드의 최신 버전에서 작동하도록 알 수 있습니까?

+0

사용하기 직전에 키와 iv 길이를 인쇄 했습니까? – zaph

+0

@zaph'iv'와'this._encryptionKey'의 길이는'16'입니다. – ThomasReggi

답변

1

repo의 포크에서 수정 프로그램을 통해 왔습니다. 나는 그것이 기본 앞뒤로 전환에 그래서 아무 의미 믿기 때문에

https://github.com/achinn/multipassify/blob/176c7664c8458cdfb8f20fac97fe27b7b7d1bff4/multipassify.js

은 "진"문의 모든

이 제거됩니다.

new Buffer(value + value)보다 Buffer.concat([value, value])이 사용되고있는 것으로 나타났습니다.

var crypto = require('crypto'); 

var BLOCK_SIZE = 16; 

var multipassify = module.exports = function(secret) { 
    if (!(this instanceof multipassify)) return new multipassify(secret); 
    if (!(typeof secret == 'string' && secret.length > 0)) throw new Error('Invalid Secret'); 

    // Use the Multipass secret to derive two cryptographic keys, 
    // one for encryption, one for signing 
    var hash = crypto.createHash("sha256").update(secret).digest(); 
    this._encryptionKey = hash.slice(0, BLOCK_SIZE); 
    this._signingKey = hash.slice(BLOCK_SIZE, 32); 
    return this; 
}; 

multipassify.prototype.encode = function(obj) { 
    if (!obj) return; 

    // Store the current time in ISO8601 format. 
    // The token will only be valid for a small timeframe around this timestamp. 
    obj["created_at"] = new Date().toISOString(); 

    // Serialize the customer data to JSON and encrypt it 
    var cipherText = this.encrypt(JSON.stringify(obj)); 

    // Create a signature (message authentication code) of the ciphertext 
    // and encode everything using URL-safe Base64 (RFC 4648) 
    var token = Buffer.concat([cipherText, this.sign(cipherText)]).toString('base64'); 
    token = token.replace(/\+/g, '-') // Replace + with - 
     .replace(/\//g, '_'); // Replace/with _ 

    return token; 
}; 

multipassify.prototype.generateUrl = function(obj, domain) { 
    if(!domain) return; 
    return "https://" + domain + "/account/login/multipass/" + this.encode(obj); 
}; 

multipassify.prototype.sign = function (data) { 
    var signed = crypto.createHmac("SHA256", this._signingKey).update(data).digest(); 
    return signed; 
} 

multipassify.prototype.encrypt = function(plaintext) { 
    // Use a random IV 
    var iv = crypto.randomBytes(BLOCK_SIZE); 
    var cipher = crypto.createCipheriv('aes-128-cbc', this._encryptionKey,iv); 

    // Use IV as first block of ciphertext 
    var encrypted = Buffer.concat([iv, cipher.update(plaintext, 'utf8'), cipher.final()]); 
    return encrypted; 
} 
관련 문제