首页 > 解决方案 > 将 256 位密钥转换为 32 位圆形密钥的问题

问题描述

我正在尝试将钥匙打成圆形钥匙。我使用结构来保存密钥:

struct key
{
    u_int64_t key[4];
    u_int32_t round_keys[8];
};

使用 func 初始化结构值:

struct key *set_key()
{
    struct key *key = malloc(sizeof(*key));
    memset(key, 0, 4 * sizeof(u_int64_t) + 8 * sizeof(u_int32_t));
    key->key[0] = 0x1;
    key->key[1] = 0x1;
    key->key[2] = 0x1;
    key->key[3] = 0x1;
    return key;
};

并使用 func 将键拍成圆形键:

void key_to_round_keys(struct key *key)
{
    memcpy(key->round_keys, key->key, sizeof(u_int32_t));
    memcpy(key->round_keys + sizeof(u_int32_t), key->key + sizeof(u_int32_t), sizeof(u_int32_t));
    memcpy(key->round_keys + 2 * sizeof(u_int32_t), key->key + 2 * sizeof(u_int32_t), sizeof(u_int32_t));
    memcpy(key->round_keys + 3 * sizeof(u_int32_t), key->key + 3 * sizeof(u_int32_t), sizeof(u_int32_t));
    memcpy(key->round_keys + 4 * sizeof(u_int32_t), key->key + 4 * sizeof(u_int32_t), sizeof(u_int32_t));
    memcpy(key->round_keys + 5 * sizeof(u_int32_t), key->key + 5 * sizeof(u_int32_t), sizeof(u_int32_t));
    memcpy(key->round_keys + 6 * sizeof(u_int32_t), key->key + 6 * sizeof(u_int32_t), sizeof(u_int32_t));
    memcpy(key->round_keys + 7 * sizeof(u_int32_t), key->key + 7 * sizeof(u_int32_t), sizeof(u_int32_t));
};

我的主要功能是

int main() {
    struct key *key = set_key();
    key_to_round_keys(key);
    printf("Key[1]: %llu\nRound key 1: %d", key->key[0], key->round_keys[0]);
    delete_key(key);
}

问题是,在将密钥打成圆形密钥期间,我的圆形密钥得到了值 {1, 0, 0, 0, 1, 0, 0, 0}。但它应该像 {0, 1, 0, 1, 0, 1, 0, 1}。为什么会这样?

标签: ccryptography

解决方案


中的指针算术key_to_round_keys都是错误的。对于指针加法,((p) + (i))等价于(&((p)[i])).

假设sizeof(u_int32_t)您的系统上是 4(这很可能),那么:

memcpy(key->round_keys + 7 * sizeof(u_int32_t), key->key + 7 * sizeof(u_int32_t), sizeof(u_int32_t));

相当于:

memcpy(&key->round_keys[7 * 4], &key->key[7 * 4], sizeof(u_int32_t));

或者:

memcpy(&key->round_keys[28], &key->key[28], sizeof(u_int32_t));

但是,round_keys数组成员只有 8 个元素长,而key数组成员只有 4 个元素长,所以这个memcpy调用的源和目标都超出了范围。


由于您的set_key函数初始化了to的key数组成员(四个 64 位数字),并且您已经表明您希望该函数将其复制到数组成员 as 中,因此您似乎想要包含和的高 32 位包含 的低 32 位。或者一般来说,应该包含 的高 32 位,并且应该包含 的低 32 位。可以这样做:struct key{1, 1, 1, 1}key_to_round_keysround_keys{0, 1, 0, 1, 0, 1, 0, 1}round_keys[0]key[0]round_keys[1]key[0]round_keys[2*n]key[n]round_keys[2*n+1]key[n]

void key_to_round_keys(struct key *key)
{
    key->round_keys[0] = key->key[0] >> 32;
    key->round_keys[1] = key->key[0] & 0xFFFFFFFFu;
    key->round_keys[2] = key->key[1] >> 32;
    key->round_keys[3] = key->key[1] & 0xFFFFFFFFu;
    key->round_keys[4] = key->key[2] >> 32;
    key->round_keys[5] = key->key[2] & 0xFFFFFFFFu;
    key->round_keys[6] = key->key[3] >> 32;
    key->round_keys[7] = key->key[3] & 0xFFFFFFFFu;
};

或者:

void key_to_round_keys(struct key *key)
{
    for (int n = 0; n < 4; n++)
    {
        key->round_keys[2*n] = key->key[n] >> 32;
        key->round_keys[2*n+1] = key->key[n] & 0xFFFFFFFFu;
    }
};

推荐阅读