无法使用 AES-256-CBC 的 pgcrypto 解密,但 AES-128-CBC 可以



我在pgcrypto中的数据解密,该数据先前已在php应用中加密。

我尝试了3种类型的加密:
1(McRypt -Rijndael 128 CBC
2(McRypt -Rijndael 256 CBC
3(openssl_encrypt-AES-256-CBC

所有内容在PHP中被加密加密,但是在PGCRYPTO中,我可以使用相同的密钥解密,而IV仅1(McRypt -Rijndael 128 CBC

这是PHP部分的示例代码:

<?php
function d ($data, $key, $mode) {
    $data = @base64_decode($data);
    $pad = $mode == MCRYPT_RIJNDAEL_256 ? 32 : 16;
    $iv = mb_substr($data, 0, $pad, "8bit");
    $data = mb_substr($data, $pad, mb_strlen($data, "8bit"), "8bit");
    if ($data === null || $data === "") {
        return $data;
    }
    if ($mode == MCRYPT_RIJNDAEL_128 OR $mode == MCRYPT_RIJNDAEL_256) {
        $data = mcrypt_decrypt($mode, $key, $data, MCRYPT_MODE_CBC, $iv);
    } else {
        $data = openssl_decrypt($data, "aes-256-cbc", $key, 0, $iv);
    }
    if ($data === false) {
        throw new Exception("Unable to decrypt data");
    }
    $padding = ord($data[mb_strlen($data, "8bit") - 1]);
    $data = mb_substr($data, 0, mb_strlen($data, "8bit") - $padding, "8bit");
    return $data;
}
function e ($data, $key, $mode) {
    $pad = $mode == MCRYPT_RIJNDAEL_256 ? 32 : 16;
    $iv = openssl_random_pseudo_bytes($pad);
    $padding = 16 - (strlen($data) % $pad);
    $data .= str_repeat(chr($padding), $padding);
    if ($mode == MCRYPT_RIJNDAEL_128 OR $mode == MCRYPT_RIJNDAEL_256) {
        $data = mcrypt_encrypt($mode, $key, $data, MCRYPT_MODE_CBC, $iv);
    } else {
        $data = openssl_encrypt($data, "aes-256-cbc", $key, 0, $iv );
    }
    if ($data === false) {
        throw new Exception("Unable to encrypt data");
    }
    return base64_encode($iv . $data);
}
$mode1 = MCRYPT_RIJNDAEL_128;
$key1 = "67pma7BQL01cqb6Nlil2T1436lLXv8Ln";
$key2 = "85f2669023b98a62d1312af75994ddf1";
$mode2 = MCRYPT_RIJNDAEL_256;
$key3 = "85f2669023b98a62d1312af75994ddf1";
$mode3 = "aes-256-cbc";
$data = "test";
$e1 = e($data, $key1, $mode1);
$e2 = e($data, $key2, $mode2);
$e3 = e($data, $key3, $mode3);
$d1 = d($e1, $key1, $mode1); //
$d2 = d($e2, $key2, $mode2); //
$d3 = d($e3, $key3, $mode3); //
//for ($i=1; $i < 4; $i++) {
//   ${"e" . $i} = e($data, ${"key" . $i}, ${"mode" . $i});
//
//    ${"d" . $i} = d(${"e" . $i}, ${"key" . $i}, ${"mode" . $i});
//}

用于代码的结果和数据:

1(McRypt -Rijndael 128 CBC

  • key =" 67PMA7BQL01CQB6NLIL2T1436LLXV8LN"
  • init vector base64 =" q5gxifw6mat4zx4tgjqimg =="
  • 加密字符串base64 =" Q5GXIFW6MAT4ZX4TGJQIMTWJGEVK66MTCRPDILKEIHY ="
  • 解密字符串base64 =" dgvzda =="

2(McRypt -Rijndael 256 CBC

  • key =" 85F2669023B98A62D1312AF75994DDF1"
  • init vector base64 =" 2emtyh cqa5x5mmty vpl5fkvwels9exrynfjggco0 ="
  • 加密字符串base64 =" 2emtyh cqa5x5mmty vpl5fkvwels9exrynfjggco3b29cc5dpfws1yafh8wuy9f0/6opc1b4sidsidsidsiDSIDSV5TOTOSV5TOTOK =="
  • 解密字符串base64 =" dgvzdawmdawmdawmdawmdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ="

3(openssl_encrypt -AES-256-CBC

  • key =" 85F2669023B98A62D1312AF75994DDF1"
  • init vector base64 =" toi xxzf6mypdpqzpzai6q =="
  • 加密字符串base64 =" toi xxzf6mypdpqzpzai6xjqymwynuvzkzkzdavnnickc5deg5mud1anpbylplew9sqjhpz29yqzrpwfk9"
  • 解密字符串base64 =" dgvzda =="

在这里我如何尝试使用相同的键在Postgres中解密此数据。

SELECT
  -- mcrypt aes 128
  decrypt_iv(
      decode('q5gXIfW6maT4zx4tgJQImtwJgEVK66mTcRPdilkEiHY=', 'base64'),
      '67pma7BQL01cqb6Nlil2T1436lLXv8Ln',
      decode('q5gXIfW6maT4zx4tgJQImg==', 'base64'),
      'aes-cbc'
  ),
  -- mcrypt aes 256
  decrypt_iv(
      decode('2EmtyH++cQA5X5mmtY+vpl5FkVwELS9ExrYnFjGGco3B29CC5DpfWs1YAfh8WuY9f0/6OPC1B4sidSV5TojJ1g==', 'base64'),
      '85f2669023b98a62d1312af75994ddf1',
      decode('2EmtyH++cQA5X5mmtY+vpl5FkVwELS9ExrYnFjGGco0=', 'base64'),
      'aes-cbc'
  ),
--     -- openssl aes 256
-- decrypt_iv(
--   decode('tOi+xXZf6MyPDpQzPZAI6XJQYmwyNUVzKzdaVnNickc5dEg5MUd1anpBYlpLeW9SQjhpZ29yQzRpWFk9', 'base64'),
--   '85f2669023b98a62d1312af75994ddf1',
--   decode('tOi+xXZf6MyPDpQzPZAI6Q==', 'base64'),
--   'aes-cbc'
-- ),
    -- pgcrypto same values as mcrypt aes 128 encrypt then decrypt
  decrypt_iv(
    encrypt_iv(
        'test',
        '67pma7BQL01cqb6Nlil2T1436lLXv8Ln',
        decode('q5gXIfW6maT4zx4tgJQImg==', 'base64'),
        'aes-cbc'),
    '67pma7BQL01cqb6Nlil2T1436lLXv8Ln',
    decode('q5gXIfW6maT4zx4tgJQImg==', 'base64'),
    'aes-cbc'
    )

您看到所有3个解密的php中的所有3个确定。在Postgres中仅(McRypt AES128CBC(解密OK - 第一个16个字节仍然是IV,但我可以删除它们并转换为文本。另外两个(McRypte AES256CBC和OpenSL256CBC(甚至看起来都没有解密。我用openssl256cbc评论了块,因为它给了我" [39000]错误:decrypt_iv错误:数据不是块大小的倍数"错误。

任何帮助将不胜感激。

MCRYPT_RIJNDAEL_256不是AES-256。这是块大小为256的Rijndael密码(因此错误(。AES是Rijndael密码的子集,使用128位的块大小,尺寸为128、192和256位。这也反映在IV大小中。

要创建AES-256加密密文,您可以使用具有正确的键大小的MCRYPT_RIJNDAEL_128(256位为32个字节(。_128 Postfix表示要使用的块大小;您仍然可以使用128、192或256位的任何有效密钥大小。


提防McRypt(尤其是基础C图书馆(不再维护。您最好使用openssl或以后的加密库库。

McRypt和OpenSL包装器还将愉快地允许无效的钥匙尺寸,只警告您 - 如果幸运的话。当然,这与大约有任何定义的AES库不兼容。

相关内容

  • 没有找到相关文章

最新更新