2017-05-29 10 views
-2

私は管理サイトをCakePHP 3.0フレームワークで開発しましたが、デフォルトのSecurity::encrypt($text, $key, $hmacSalt = null)を使用してAPI認可のトークンを暗号化しています。CakePHP 3.0で暗号化し、NodeJSで復号化する

私はまた、リアルタイム通信用の単純なNodeJSサービスを持っています。私はAPIとこのリアルタイム通信に同じトークンを使用したいと思います。

さまざまな方法でNodeJSにCakePHP復号化機能を書き直そうとしていますが、正しい結果が得られません。以下は、CakePHPは機能を復号化された:CakePHPのから

public static function decrypt($cipher, $key) 
    { 
     $method = 'AES-256-CBC'; 
     $ivSize = openssl_cipher_iv_length($method); 

     $iv = mb_substr($cipher, 0, $ivSize, '8bit'); 

     echo "---- IV --- \r\n"; 
     var_dump($iv); 

     $cipher = mb_substr($cipher, $ivSize, null, '8bit'); 

     echo "---- KEY --- \r\n"; 
     var_dump($key); 

     echo "---- CIPHER LAST --- \r\n"; 
     var_dump($cipher); 

     return openssl_decrypt($cipher, $method, $key, OPENSSL_RAW_DATA, $iv); 
    } 

結果:

---- IV --- 
string(16) "��r�N3U�Y6Q�#��" 
---- KEY --- 
string(32) "1c494314996afe280bc5981c4e185f79" 
---- CIPHER LAST --- 
string(160) "~a�xh�z��+���M����j*!�(����f�ZG;�)w��Kl�3�m��Z��ە��OR9~���6[X�/��n��B6��C��˟f��!6��1���|S��*�mG+���OR�kr��t�;�+�㟱��"���<i����e:��" 

ここではNodeJSの私の簡単なコードです:NodeJSから

var buf = new Buffer(socket.handshake.query.token, 'base64').toString('utf8', 64); 
var iv = buf.substr(0,16); 

console.log("-----IV------") 
console.log(iv); 

var key = sha256(config.tokenKey+config.tokenSalt).substr(0,32); 
console.log("-----KEY------") 
console.log(key); 

var cipher = buf.substr(16); 

console.log("------CIPHER-----"); 
console.log(cipher); 

var decipher = crypto.createDecipheriv('AES-256-CBC', key, iv); 
//decipher.setAutoPadding(false); 
var dec = decipher.update(cipher); 
dec += decipher.final('utf-8'); 

結果:

-----IV------ 
��r�N3U�Y6Q�#�� 
-----KEY------ 
1c494314996afe280bc5981c4e185f79 
------CIPHER----- 
~a�xh�z��+���M��� 
       ��j*!�(����f�ZG;�)w��Kl��m���Z����ە��OR9~���6[X�/��n��B6��C��˟f���!6��1���|S��*�mG+���OR�kr��t�;�+�㟱��"���<i����e:�� 
crypto.js:239 
    this._handle.initiv(cipher, toBuf(key), toBuf(iv)); 
Error: Invalid IV length 

私は別のIVを作成しようとする私は例外を避けるために成功したとしても正しい結果を得られなくても、PHPコードの "8bit"エンコーディングであると想定しています。

誰かがこれを解決する方法を知っているなら、私は非常に感謝しています!

答えて

0

私はNode.jsをよく知っているわけではありませんが、入力をUTF-8文字列に変換するとデータが不正になり、バイナリデータで作業する必要があります。文字列。

あなたが実際に文字列に何かを変換する必要があるまで、私は、少なくともそれは私がCakePHPによる暗号化されたデータを復号化するために持っていたとき、私はそれをやった方法です、バッファで動作するようにお勧めしたい:

var data = Buffer.from(socket.handshake.query.token, 'base64'); 
var key = config.tokenKey; 
var salt = config.tokenSalt; 
var hmacSize = 64; 
var ivSize = 16; 
var keySize = 32; 

var encrypted = data.slice(hmacSize); 

key = crypto 
    .createHash('sha256') 
    .update(key + salt) 
    .digest('hex') 
    .substr(0, keySize); 

var iv = encrypted.slice(0, ivSize); 

encrypted = encrypted.slice(ivSize); 

var decipher = crypto.createDecipheriv('AES-256-CBC', key, iv); 
var decrypted = Buffer.concat([ 
    decipher.update(encrypted), 
    decipher.final() 
]); 

console.log(decrypted.toString('utf8'));