1

我需要在 c++ 中对一些数据进行编码并在 php 中对其进行解码,但是 php 没有正确解码。我检查了用相同的密钥和 iv 对同一消息进行编码,结果之间存在差异。这是我的代码:

struct ctr_state
{
    unsigned char ivec[AES_BLOCK_SIZE];
    unsigned int num;
    unsigned char ecount[AES_BLOCK_SIZE];
};
unsigned char indata[AES_BLOCK_SIZE];
unsigned char outdata[AES_BLOCK_SIZE];
unsigned char iv[AES_BLOCK_SIZE];

struct ctr_state state;

int init_ctr(struct ctr_state *state, const byte iv[16])
{
    /* aes_ctr128_encrypt requires 'num' and 'ecount' set to zero on the
     * first call. */
    state->num = 0;
    memset(state->ecount, 0, AES_BLOCK_SIZE);

    /* Initialise counter in 'ivec' to 0 */
    memset(state->ivec + 8, 0, 8);

    /* Copy IV into 'ivec' */
    memcpy(state->ivec, iv, 8);
}

void aes_encoder(byte *read, byte *write, int size, byte *enc_key, byte *iv)
{
    AES_KEY key;
    if (AES_set_encrypt_key(enc_key, 128, &key) < 0)
    {
       Logger::getInstance()->Error("problem with setting encrypt key");
    }
    init_ctr(&state, iv);

    AES_ctr128_encrypt(read, write, size, &key, state.ivec, state.ecount, &state.num);
}

byte *key = (byte*)"2123456789012345";
byte *iv = (byte*)"2asdasdasdasdasd";

QByteArray message = "this is message";
byte *data = reinterpret_cast<byte *>(message.data());

aes_encoder(data, data,  message.size(), key, iv);
qDebug() << message.toBase64();

结果是:“hF/nlW4e+FmuF8Bfny9M”

和php代码:

<?php
$message = "this is message";
$key = "2123456789012345";
$iv = "2asdasdasdasdasd";

$encrypted = openssl_encrypt($message, 'aes-128-ctr', $key, true, $iv);

echo base64_encode($encrypted);

结果:“RLLUkP54El9FCeWpO/bI”

为什么结果不一样?

4

1 回答 1

2

您的问题是您没有以标准方式使用 CTR 模式。在init_ctr您只复制提供的 IV 的 8 个字节并将其余部分设置为零。相反,如果您使用整个 IV,您将获得与 PHP 代码相同的结果:

//don't do this:
//memset(state->ivec + 8, 0, 8);
//memcpy(state->ivec, iv, 8);  

//do this:
memcpy(state->ivec, iv, AES_BLOCK_SIZE);  

教训是,仅仅因为你在某处找到了一些代码,并不意味着你可以在不了解它在做什么的情况下复制粘贴它。对于加密代码尤其如此。如果您甚至了解分组密码是什么以及如何在 CTR 模式下工作的基础知识,您就会立即意识到您的代码存在的问题。

哦,重要的安全提示:使用 CTR 模式时,切勿使用相同的 IV 加密多条消息。否则你会死。

于 2013-07-28T17:42:07.023 回答