在Nodejs中加密并在PHP中解密

我正在尝试解密最初在NodeJS中加密的PHP字符串。</ p>
\ ñ

PHP:</ p>

<代码> openssl_decrypt($ raw_id, “AES-128-CBC”, “s7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m”,0,NULL)</代码> </ p> \ n

这似乎总是返回 false </ code>。</ p>

Nodejs中的加密:</ p>

  function 加密(文本){
变种密码= crypto.createCipher( 'AES-128-CBC', 's7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m');
变种加密= cipher.update(文字, 'UTF8', '六角')
加密+ = cipher.final('hex')

返回加密;

功能解密(文本){
var cipher = crypto.createDecipher('aes-128-cbc','s7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m');
var decrypted = cipher.update(text,'hex',' utf8')
解密+ = cipher.final('utf8');

返回解密;
}
</ code> </ pre>

我基本上想要加密, 例如,<代码>加密( “比萨饼”)</代码>在的NodeJS,将其发送到PHP页面(<码> 3879f91a59e9a458db62f905b0a488a1 </代码>),并从那里解密它(<码> openssl_decrypt:返回披萨< /code>).


nn

我知道这段代码不安全,因为我没有使用IV,但我不知道如何添加。</ i> </ p>
</ div>

展开原文

原文

I'm trying to decrypt a string in PHP which was originally encrypted in NodeJS.

PHP:

openssl_decrypt($raw_id, "aes-128-cbc", "s7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m", 0, null)

This seems to always returnfalse.

Encryption in Nodejs:

function encrypt(text) {
    var cipher = crypto.createCipher('aes-128-cbc', 's7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m');
    var encrypted = cipher.update(text, 'utf8', 'hex')
    encrypted  += cipher.final('hex')

    return encrypted; 
}

function decrypt(text) {
    var cipher = crypto.createDecipher('aes-128-cbc', 's7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m');
    var decrypted = cipher.update(text, 'hex', 'utf8')
    decrypted += cipher.final('utf8');

    return decrypted;
}

I basically want to encrypt, for example, encrypt("Pizza") in Nodejs, send it to the PHP page (3879f91a59e9a458db62f905b0a488a1), and decrypt it from there (openssl_decrypt: return Pizza).

I know this code is not safe, since I'm not using an IV but I'm not sure how to add one.

1个回答

Your method is not secure and can also be victim to man in the middle attacks, you should always use a IV and a HMAC
You can encrypt in php like this

$key = substr('encyptionsec123342',0,32)
function encrypt ($message, $method, $secret, &$hmac) {
    $iv = substr(bin2hex(openssl_random_pseudo_bytes(16)),0,16);
    $encrypted = base64_encode($iv) . openssl_encrypt($message, $method, $secret, 0, $iv);
    $hmac = hash_hmac('md5', $encrypted, $secret);
    return $encrypted;
}

function decrypt ($encrypted, $method, $secret, $hmac) {
    if (hash_hmac('md5', $encrypted, $secret) == $hmac) {
        $iv = base64_decode(substr($encrypted, 0, 24));
        return openssl_decrypt(substr($encrypted, 24), $method, $secret, 0, $iv);
    }
}

function encryptWithTSValidation ($message, $method, $secret, &$hmac) {
    date_default_timezone_set('UTC');
    $message = substr(date('c'),0,19) . "$message";
    return encrypt($message, $method, $secret, $hmac);
}

function decryptWithTSValidation ($encrypted, $method, $secret, $hmac, $intervalThreshold) {
    $decrypted = decrypt($encrypted, $method, $secret, $hmac);
    $now = new DateTime();
    $msgDate = new DateTime(str_replace("T"," ",substr($decrypted,0,19)));
    if (($now->getTimestamp() - $msgDate->getTimestamp()) <= $intervalThreshold) {
        return substr($decrypted,19);
    }
}

This is a secure AES-256-CBC method and with HMAC to stop man in the middle attacks.
Node.js

var secret = "encyptionsec123342";
secret = secret.substr(0, 32);
var method = 'AES-256-CBC';
var encrypt = function(message, method, secret, hmac) {
    var iv = crypto.randomBytes(16).toString('hex').substr(0, 16);
    var encryptor = crypto.createCipheriv(method, secret, iv);
    var encrypted = new Buffer.alloc(iv).toString('base64') + encryptor.update(message, 'utf8', 'base64') + encryptor.final('base64');
    hmac = crypto.createHmac('md5', secret).update(encrypted).digest('hex');
    return encrypted;
};
var decrypt = function(encrypted, method, secret, hmac) {
    if (crypto.createHmac('md5', secret).update(encrypted).digest('hex') == hmac) {
        var iv = new Buffer.from(encrypted.substr(0, 24), 'base64').toString();
        var decryptor = crypto.createDecipheriv(method, secret, iv);
        return decryptor.update(encrypted.substr(24), 'base64', 'utf8') + decryptor.final('utf8');
    }
};
var encryptWithTSValidation = function(message, method, secret, hmac) {
    var messageTS = new Date().toISOString().substr(0, 19) + message;
    return encrypt(messageTS, method, secret, hmac);
}
var decryptWithTSValidation = function(encrypted, method, secret, hmac, intervalThreshold) {
    var decrypted = decrypt(encrypted, method, secret, hmac);
    var now = new Date();
    var year = parseInt(decrypted.substr(0, 4)),
        month = parseInt(decrypted.substr(5, 2)) - 1,
        day = parseInt(decrypted.substr(8, 2)),
        hour = parseInt(decrypted.substr(11, 2)),
        minute = parseInt(decrypted.substr(14, 2)),
        second = parseInt(decrypted.substr(17, 2));
    var msgDate = new Date(Date.UTC(year, month, day, hour, minute, second))
    if (Math.round((now - msgDate) / 1000) <= intervalThreshold) {
        return decrypted.substr(19);
    }
}

To perform encryption and decryption in php,

$encrypted = encryptWithTSValidation($recipent, $method, $key, $hmac);
$decrypted = decryptWithTSValidation($encrypted,$method,$key, $hmac, 60*60*12)//this is 12 hours 

to generate a hmac, you can use simple md5 hashing

$hmac = hash_hmac('md5', $recipent, $key);

and in node.js

var decrypted = decryptWithTSValidation(encString, method, secret, hmac, 60 * 60);
var encrypted = decryptWithTSValidation(string, method, secret, hmac);

NOTE: Make sure to make a unique key that is of 32 bit and is same while encryption and decryption in nodejs and php. Also keep it safe and never store it in a database.
Code Reference : Encrypt string in PHP and decrypt in Node.js

duanqiang7631
duanqiang7631 你的密钥不是长度32.检查它,看它是否是一个有效的密钥。 或者您可以在线创建随机AES密钥,只需确保其32位
大约一年之前 回复
dtvnbe1428
dtvnbe1428 Hello @ window.document我试图使用你的上面的代码,但有错误显示我看到:screencast.com/t/HCGHVEkkb8j0,你能帮我解决一下我该怎么办?
大约一年之前 回复
dongyouzhi7218
dongyouzhi7218 不,我的意思是操作可能在直接通信中使用它像websockets也许这就是为什么他像我曾经做过的那样整合node.js和php
一年多之前 回复
dongwu9972
dongwu9972 MitM攻击者
一年多之前 回复
drfls28608
drfls28608 nodejs用于“实时”应用程序,用户可能在Web套接字等中使用它。
一年多之前 回复
duancongduo4109
duancongduo4109 什么是MitM攻击? 如果您想建议一个更好的替代方案,建议将认证加密建议为包含在TLS 1.4中的AES-GCM
一年多之前 回复
duanne9313
duanne9313 乐于帮助
一年多之前 回复
douzhuan1432
douzhuan1432 这肯定会有所帮助,非常感谢!
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问