0

我正在编写一些 PHP 代码来执行 AES 字符串加密和解密。加密工作正常,但我似乎无法解密它。

下面是进行加密并添加所需填充的代码。

function encrypt($data) 
    { 
        $iv = "PRIVATE";
        $key = CIPHERKEY;

        return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, addpadding($data), MCRYPT_MODE_CBC, $iv));
    }

    function addpadding($string, $blocksize = 16)
    {
        $len = strlen($string);
        $pad = $blocksize - ($len % $blocksize);
        $string .= str_repeat(chr($pad), $pad);

        return $string;
    }

上面的代码运行良好,下面的代码在解密时一直失败。我尝试进行解密,然后剥离填充,但填充函数总是返回 false。

下面是进行解密和剥离的代码。

function strippadding($string)
{
    $slast = ord(substr($string, -1));
    $slastc = chr($slast);
    $pcheck = substr($string, -$slast);
    if(preg_match("/$slastc{".$slast."}/", $string)){
        $string = substr($string, 0, strlen($string)-$slast);
        return $string;
    } else {
        return "false";
    }
}

    function decrypt($data)
    {
        $iv = "PRIVATE";
        $key = CIPHERKEY;

        //$decoded = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
        $decrytped = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
        $base64Decoded = base64_decode($decrytped);
        return strippadding($base64Decoded);
    }

感谢您的任何帮助,您可以提供。

4

2 回答 2

3

在您的解密方法中,解密和 base64 步骤是倒退的。重要的是,无论您以何种顺序进行加密操作,您都可以反向进行解密。

在您的加密方法中,您正在对密文进行 base64 编码:

base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, addpadding($data), MCRYPT_MODE_CBC, $iv));

解密时,您需要撤消 base64 编码,然后解密该结果。

$base64Decoded = base64_decode($data);
$decrytped = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $base64Decoded, MCRYPT_MODE_CBC, $iv);

此外,看起来 mcrypt 将处理填充不均匀块,因此您的 addpadding() 方法可能是多余的。

于 2013-01-27T23:27:06.530 回答
0

您使用的 IV 太短,小于块大小。我假设这会导致在解密时使用不同的 IV。Blocksize 是 16 个字节,所以 IV 应该是 16 个字节,但是您的固定字符串 IV 只有 7 个字节(如果计算底层 C 代码可能添加的终止零字节,则为 8 个字节)。

而不是使用固定字符串,您应该使用由mcrypt_create_iv(). 您可以使用PHP 手册mcrypt_get_iv_size()中的示例 1 中所示的方法找出一个块的长度。mcrypt_create_iv()然后,您将发送/存储附加到密文的随机 IV,以便您知道 IV 在解密时是什么。

此外,mcrypt 自己填充,所以你不需要。而且,正如 mfanto 指出的那样,您需要在解密之前而不是之后解码 Base64。

于 2013-01-27T23:26:41.927 回答