Шифрование в Nodejs и дешифрование в PHP - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь расшифровать строку в PHP, которая была изначально зашифрована в NodeJS.

PHP:

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

Это, кажется, всегда возвращает false.

Шифрование в 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;
}

Я в основном хочу зашифровать, например, encrypt("Pizza") в Nodejs, отправить его на страницу PHP (3879f91a59e9a458db62f905b0a488a1) и расшифроватьэто оттуда (openssl_decrypt: return Pizza).

Я знаю, что этот код небезопасен, так как я не использую IV, но я не уверен, как его добавить.

1 Ответ

0 голосов
/ 02 февраля 2019

Ваш метод небезопасен и также может быть жертвой атакующих атакующих, вы всегда должны использовать IV и HMAC
Вы можете зашифровать в php следующим образом:

$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);
    }
}

Этобезопасный метод AES-256-CBC и HMAC для остановки атак «человек посредине».
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);
    }
}

Для выполнения шифрования и дешифрования в php,

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

для создания hmac вы можете использовать простое хеширование md5

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

и в файле node.js

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

ПРИМЕЧАНИЕ: Убедитесь, что вы создали уникальный ключон 32-битный и одинаковый при шифровании и дешифровании в nodejs и php.Также сохраняйте его в безопасности и никогда не храните в базе данных.
Ссылка на код: Зашифруйте строку в PHP и расшифруйте в Node.js

...