douyimin1083 2017-04-21 19:44
浏览 170

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

I have problem decrypting data in pgcrypto that was previously encrypted in PHP app.

I tried 3 types of encryption:
1) mcrypt - RIJNDAEL 128 CBC
2) mcrypt - RIJNDAEL 256 CBC
3) openssl_encrypt - aes-256-cbc

everything is encrypted decrypted fine in PHP, but in pgcrypto I can decrypt using same key and iv only 1) mcrypt - RIJNDAEL 128 CBC

Here is example code for PHP part:

<?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});
//}

Results and data used to code:

1) mcrypt - RIJNDAEL 128 CBC

  • key = "67pma7BQL01cqb6Nlil2T1436lLXv8Ln"
  • init vector base64 = "q5gXIfW6maT4zx4tgJQImg=="
  • encrypted string base64 = "q5gXIfW6maT4zx4tgJQImtwJgEVK66mTcRPdilkEiHY="
  • decrypted string base64 = "dGVzdA=="

2) mcrypt - RIJNDAEL 256 CBC

  • key = "85f2669023b98a62d1312af75994ddf1"
  • init vector base64 = "2EmtyH++cQA5X5mmtY+vpl5FkVwELS9ExrYnFjGGco0="
  • encrypted string base64 = "2EmtyH++cQA5X5mmtY+vpl5FkVwELS9ExrYnFjGGco3B29CC5DpfWs1YAfh8WuY9f0/6OPC1B4sidSV5TojJ1g=="
  • decrypted string base64 = "dGVzdAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAA="

3) openssl_encrypt - aes-256-cbc

  • key = "85f2669023b98a62d1312af75994ddf1"
  • init vector base64 = "tOi+xXZf6MyPDpQzPZAI6Q=="
  • encrypted string base64 = "tOi+xXZf6MyPDpQzPZAI6XJQYmwyNUVzKzdaVnNickc5dEg5MUd1anpBYlpLeW9SQjhpZ29yQzRpWFk9"
  • decrypted string base64= "dGVzdA=="

Here how I am trying to decrypt this data in Postgres using same Keys and IV.

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'
    )

As you see all 3 decrypted OK in PHP. In Postgres only first (mcrypt aes128cbc) decrypted OK - first 16 bytes still are IV, but I could remove them and convert to text. Two others (mcrypte AES256CBC and openssl256cbc) are not even looking like they were decrypted. I commented block with openssl256cbc since it gives me "[39000] ERROR: decrypt_iv error: Data not a multiple of block size" error.

Any help will be appreciated.

  • 写回答

1条回答 默认 最新

  • duanhao9176 2017-04-24 10:36
    关注

    MCRYPT_RIJNDAEL_256 isn't AES-256. It's the Rijndael cipher with a block size of 256 (hence the error). AES is a subset of the Rijndael cipher using block size of 128 bits and key sizes of 128, 192 and 256 bits. This is also reflected in the IV size.

    To create an AES-256 encrypted ciphertext you can use MCRYPT_RIJNDAEL_128 with the correct key size (256 bits is 32 bytes). The _128 postfix indicates the block size to be used; you can still use it with any valid key size of 128, 192 or 256 bit.


    Beware that mcrypt - especially the underlying C-library - is not maintained anymore. You're better off using the openssl or later crypto libraries.

    The mcrypt and OpenSSL wrappers will also happily allow invalid key sizes, only warning you - if you're lucky. That's of course not compatible with about any well defined AES library.

    评论

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度