2014-12-31 2 views
3

에 :다시 MCRYPT_RIJNDAEL_128는 Node.js를 Node.js를에서 다음과 PHP를 암호화 코드를 다시 시도

$size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); 
$iv = mcrypt_create_iv($size, MCRYPT_RAND); 
$msg = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, 'MY_KEY_LONG_STRING', 'PLAINTEXT', MCRYPT_MODE_ECB, $iv)); 

이 시도 :

var text = 'PLAINTEXT'; 
var len = text.length; 
for (var i = 0; i < 16 - len % 16; i++) { // pad to multiple of block size 
    text += '\0'; 
} 
var key = 'MY_KEY_LONG_STRING'; 
key = key.substr(0, 16); // trim to expected key size for aes128 

var cipher = crypto.createCipher('aes-128-ecb', key); 
cipher.setAutoPadding(false); // did our own padding, to match mcrypt_encrypt 
var encrypted = cipher.update(text, 'utf8', 'base64'); 
encrypted += cipher.final('base64'); 

는 PHP 하나에서 다른 결과를 얻기 ...

또한 IV (aes-128-ecb에서 사용하지 않아야 함)를 사용하여 암호 생성을 시도했습니다.

var cipher = crypto.createCipheriv('aes-128-ecb', key, ''); 

또한 php와 다른 결과입니다. 모든 아이디어가 어떻게 PHP 버전과 똑같이 동작하게 만드나요?

+0

는 ECB 그래서 PHP 코드가 응축 될 수 있으며, 정맥 주사를 사용할 수 없습니다 :'$ msg = base64_encode (mcrypt_encrypt (MCRYPT_RIJNDAEL_128, 'MY_KEY_LONG_ST –

답변

3

오히려 불리하게 구성된 두 개의 라이브러리를 재생하면 재미있을 수 있습니다. 오히려 모든 일을보다 요청에 따라, 나는 아이디어와 함께 당신을 도울 수 있습니다 :

키 바이트를 제거하면, PHP 그들이 다음 사용 가능한 키 크기에 제로 패딩을 사용하여 확장보다는
  • -192 비트 또는 24이 될 것이라고 귀하의 상황에서 바이트; 이렇게하려면 알고리즘으로 aes-192-ecb을 지정해야합니다. (대체로 MCRYPT_RIJNDAEL_128을 사용해야하지만, PHP에서 128은 키 크기가 아닌 블록 크기입니다)
  • 패딩이 올바르지 않습니다. PHP 패드 0..15 제로 바이트 1.16 바이트 대신
  • 두 번째 인수는 암호이므로 2 인수 createCipher을 사용할 수 없습니다. 대신 세 개의 인수 createCipher를 사용하고 IV는

PHP의 IV 코드는 불필요 난수 생성기를 세금, 어떤 16 바이트 IV를 제공 할 필요가 있도록 한 것을 사용하는 경우 Node.js를 키 유도을 수행 사용되지 않습니다.


코드 패딩

var padSize = 16 - ((len + 16 - 1) % 16 + 1); 
for (var i = 0; i < padSize; i++) { // pad 0 .. 15 until to multiple of block size 
    text += '\0'; 
} 

을 할 수 또는 당신은 당신의 자신의 패딩 방법 하지 않는 한len % 16 == 0 사용할 수 있습니다.

+0

기본 면책 조항 : ECB는 안전하지 않으며 MAC이없는 데이터를 전송하는 것이 안전하지 않습니다. 또한 JavaScript 및 PHP를 암호화에도 사용하는 것에 대해 큰 의의가 있습니다. –

+0

안녕하세요, Maarten, 아이디어를 주셔서 감사합니다 : 1) 24 바이트를 패딩하고'crypto.createCipheriv'를 호출하면, node.js는'node-crypto : Invalid key length 24' 오류를 제공합니다. php가 24 바이트로 확장된다는 사실은 도움이된다. 2) "PHP pads 0..15 ..."는 무엇을 의미합니까? 3) PHP의 IV 코드는 주석에 따라 판단하여 이전 버전의 PHP에서 IV 인수를 제공하지 않을 때 발생했던 오류를 피할 수 있습니다. –

+0

@PashaBitz 1) 24 바이트 주요 문제에 대한 해결책을 찾기 위해 변경된 대답 (첫 번째 항목에서)을 확인하십시오. 2) PHP 블록은 다음 블록 크기에 도달 할 때까지 0으로 채워지지만 이미 크기가 x 배인 블록 크기에서는 전혀 채워지지 않습니다. 3) IV에 관해서는, 나는 모든 0으로 초기화 된 16 바이트의 바이트 배열을 제공 할 것입니다. IV가 사용되지 않는다면 IV를 제공해야 할 수도 있지만 무작위 화하는 것은 의미가 없습니다. –

1

다음은 PHP에서 NodeJS 로의 마이그레이션 문제를 해결하는 코드입니다. 나는 aes-256-ecb을 사용해야하므로 32 바이트의 엄격한 키가 있습니다.

PHP 코드 나는 다시 원하는 :

$text = "Some super mega text I want to encode"; 
$skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq"; 

function encode($text,$skey) { 
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $skey, $text, MCRYPT_MODE_ECB, $iv); 
    return base64_encode($crypttext); 
} 

echo encode($text,$skey); 

출력 :

dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD 

NodeJS :

var crypto = require('crypto'); 

var text = "Some super mega text I want encode"; 
var skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq"; 

function encode(text, skey) { 
    var len = text.length; 
    var padSize = 16 - ((len + 16 - 1) % 16 + 1); 
    for (var i = 0; i < padSize; i++) { 
     text += '\0'; 
    } 
    var cipher = crypto.createCipheriv('aes-256-ecb', skey, ''); 
    cipher.setAutoPadding(false); 
    var encrypted = cipher.update(text, 'utf8', 'base64'); 
    encrypted += cipher.final('base64'); 
    return encrypted; 
} 

console.log(encode(text, skey)); 

출력 :

012 3,516,
dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD 

또한 Mcrypt 라이브러리 패키지가 작동 NodeJS :

npm install mcrypt 

코드 :

var text = "Some super mega text I want encode"; 
var skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq"; 

function encode(text, skey) { 
    var MCrypt = require('mcrypt').MCrypt; 
    var rijEcb = new MCrypt('rijndael-128', 'ecb'); 
    rijEcb.open(skey); 
    var ciphertext = rijEcb.encrypt(text); 
    return ciphertext.toString('base64'); 
} 

console.log(encode(text, skey)); 

출력 :

dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD 
관련 문제