在PHP 7.2中解密PBKDF2加密的会话密钥

时间:2019-02-27 17:01:08

标签: encryption php-7.2 pbkdf2

我需要将我照顾的网站升级到PHP 7.2。在测试阶段,我发现该站点上的一个插件使用了mcrypt库,该库在PHP 7.2中不再可用。

本质上,此插件从票务系统(Tessitura)接收PBKDF2加密的数据,该系统返回用户的会话密钥,时间戳和加密的字符串。

在控制面板中,我得到了用于解密此会话密钥的数据,例如密码,盐,身份验证/ HMAC密钥,BlockSize,PaddingMode,EncryptionKeyIterations,EncryptionKeyLength和HMACLength

Image of supplied fields

我一直在努力寻找如何解密数据的方法,但是我承认自己正在努力。 C

有人告诉我如何使用php 7.2实现吗?我在openssl套件中发现了一些函数,这些函数看起来可能是正确的方法,但是它们对我提供的信息都使用了不同的术语,因此我无法确定从哪里开始,在哪里进行什么或进行哪些设置使用

在此先感谢任何可以解决此问题的人!

1 个答案:

答案 0 :(得分:0)

正如Rob Napier所说,PBKDF2是系统用来对传递给加密过程的密码进行哈希处理的东西。该站点实际上正在使用aes-256-cbc加密。该加密过程可以包括密码。

信息加密后,将使用HMAC密钥对该有效负载进行签名。

您可以使用openSSL库在php 7及更高版本中执行所有这些操作。这是一些示例代码,它们创建一个类来处理加密/解密,例如:


$crypto = new AesCryptoClass('YOUR_PASSPHRASE_HERE',
                        'YOUR_HMAC_KEY_HERE',
                        'YOUR_SALT_HERE');
class AesCryptoClass {

    // These should not change
    private $hmacLength = 32;
    private $iterations = 1000;
    private $keyLength = 32;
    private $blockSize = 16;
    private $cipher = 'aes-256-cbc';

    function __construct($password,$hmacKey,$salt)
        {
            $this->password = $password;
            $this->hmacKey  = $hmacKey;
            $this->salt     = $salt;
        }

    function encrypt($plainText)
        {
            $iv = openssl_random_pseudo_bytes(16); 

            $encryptedBytes = $this->encryptInner($iv, $plainText);

            $encryptedMessage = $iv . $encryptedBytes;

            $mac = $this->hashMessage($encryptedMessage);

            $secureMessage = $mac . $encryptedMessage;

            $encryptedText = base64_encode($secureMessage);

            return $encryptedText;
        }

    function decrypt($encryptedText)
        {
            $secureMessage = base64_decode($encryptedText);

            $mac = substr($secureMessage, 0, $this->hmacLength);

            $encryptedMessage = substr($secureMessage, $this->hmacLength);

            $newMac = $this->hashMessage($encryptedMessage);

            if (strcmp($mac, $newMac) !== 0) {
                return "";
            }

            $iv = substr($encryptedMessage,0, $this->blockSize);

            $encryptedBytes = substr($encryptedMessage, $this->blockSize);

            $plainText = $this->decryptInner($iv, $encryptedBytes);

            return $plainText;
        }

    function encryptInner($iv, $plainText)
        {
            $encryptionKey = openssl_pbkdf2($this->password, $this->salt, $this->keyLength, $this->iterations);
            return openssl_encrypt($plainText, $this->cipher, $encryptionKey, OPENSSL_RAW_DATA, $iv);
        }

    function decryptInner($iv, $encryptedBytes)
        {
            $encryptionKey = openssl_pbkdf2($this->password, $this->salt, $this->keyLength, $this->iterations);
            return openssl_decrypt($encryptedBytes, $this->cipher, $encryptionKey, OPENSSL_RAW_DATA, $iv);
        }

    function hashMessage($encryptedMessage)
        {
            return pack("H*", hash_hmac("sha256", $encryptedMessage, $this->hmacKey));
        }
}

此代码和过程描述也包含在Wiki的底部: https://bitbucket.org/TN_WebShare/webpro-session-sharing-sample/wiki/Session%20Key%20Encryption%20and%20Decryption