dousigan0499 2019-02-02 14:40
浏览 442
已采纳

在Nodejs中加密并在PHP中解密

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条回答 默认 最新

  • doxqszx09742 2019-02-02 16:51
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 wincc已组态的变量过多
  • ¥60 如图:直线与椭圆X轴平行,求直线与椭圆任意一点的相切坐标计算公式
  • ¥50 如何用python使用opencv里的cv::cudacodec::VideoWriter函数对视频进行GPU硬编码
  • ¥100 c#solidworks 二次开发 工程图自动标边线法兰 等折弯尺寸怎么标
  • ¥15 halcon DrawRegion 提示错误
  • ¥15 FastAPI Uvicorn启动显示404
  • ¥15 centos7.9脚本,怎么排除特定的访问记录
  • ¥15 关于#Django#的问题:我的静态文件呢?
  • ¥15 关于CPLEX的问题,请专家解答
  • ¥15 cocos的点击事件 怎么穿透到 原生fragment上。