我写的加密算法中的CBC模式不能用解密函数解密加密函数加密后的数据

问题描述 投票:0回答:0

我写了一个对称加密算法,其加密过程类似于AES和SM4。 和AES一样,采用SP结构的分组形式
和SM4一样,都是从第一轮密钥加密到最后一轮密钥,解密从最后一轮密钥到第一轮密钥。
它使用了一个非常类似于AES结构的加密过程(至于为什么要写这个算法,是为我以后的项目做铺垫)。我参考了AES加密算法的源码(因为它是目前世界上最安全的对称加密算法之一)
但是,我的加密算法项目目前遇到了一个问题。正如标题所说,不能使用对应的CBC解密函数来解密加密数据
CBC模式我参考了GitHub上一些仓库中AES加密算法的源码,也参考了CBC模式的定义和解释
我写的CBC模式加密没问题,就是从packet 1到packet 2再到packet N。 但是在解密的时候,我写不好这个过程,导致无法使用解密函数进行解密。
如果你能给我一个好的答案,我会采纳你的答案。非常感谢!

以下是我的对称加密算法的部分源代码和异常代码:

snByte == uint8_t, snSize_t == size_t

snc.h

#ifndef __SNC_H__
#define __SNC_H__

#include <snBits.h>

// #define SNC_256 // 32 bytes
#define SNC_512 // 64 bytes
// #define SNC_768 // 96 bytes

#define SNC_BLOCKLEN 32 // 区块长度(Block size)

#define SNC_NB 8 // 纵向长度(Longitudinal length)
#define SNC_NK 4 // 横向长度(Transverse length)

#if defined(SNC_768)
#define SNC_NR 13 // 加解密轮数(Number of encryption and decryption rounds)
#define SNC_KEYLEN 96 // 密钥长度(Key length)
#elif defined(SNC_512)
#define SNC_NR 11
#define SNC_KEYLEN 64
#else
#define SNC_NR 9
#define SNC_KEYLEN 32
#endif

#ifndef bitSwap
// 二进制位切换,示例: 0xb8 -> bitSwap -> 0x8b
// bit swap, example: 0xb8 ->bitSwap ->0x8b
#define bitSwap(x) (((x & 0x0f) << 4) ^ (x >> 4))
#endif

typedef snByte sncState_t[SNC_NB][SNC_NK]; // Declare block type
typedef struct {
    snByte iv[SNC_BLOCKLEN];
    snByte rk[SNC_NR][SNC_KEYLEN];
} SNC_ctx; // Declare the data structure of SNC algorithm

snVoid SNC_init_ctx(SNC_ctx *ctx, const snByte *keyBuf);
snVoid SNC_ECB_Encrypt(SNC_ctx *ctx, snByte *buf, snSize_t size);
snVoid SNC_ECB_Decrypt(SNC_ctx *ctx, snByte *buf, snSize_t size);
snVoid SNC_CBC_Encrypt(SNC_ctx *ctx, snByte *buf, snSize_t size);
snVoid SNC_CBC_Decrypt(SNC_ctx *ctx, snByte *buf, snSize_t size);

#endif

snc.c

// Use the XOR function of plaintext or ciphertext block and initial vector block for CBC mode
static snVoid SNC_XorWithIV(sncState_t *buf, sncState_t *iv)
{
    register sn_u32 i;
    for(i = 0; i < SNC_NK; ++i) {
        // 按列异或
        (*buf)[0][i] ^= (*iv)[0][i];
        (*buf)[1][i] ^= (*iv)[1][i];
        (*buf)[2][i] ^= (*iv)[2][i];
        (*buf)[3][i] ^= (*iv)[3][i];
        (*buf)[4][i] ^= (*iv)[4][i];
        (*buf)[5][i] ^= (*iv)[5][i];
        (*buf)[6][i] ^= (*iv)[6][i];
        (*buf)[7][i] ^= (*iv)[7][i];
    }
}

// Encrypt block function to encrypt the input block
static snVoid SNC_Cipher(sncState_t *state, sncState_t *RoundKey)
{
    register sn_u32 i;

    // Execute block replacement function
    SNC_SubBytes(state);

    for(i = 0; i < SNC_NK; ++i) {
        // This block is the basic encryption, that is, encryption using a key of [0 - 31] bytes
        (*state)[0][i] ^= (*RoundKey)[0][i];
        (*state)[1][i] ^= (*RoundKey)[1][i];
        (*state)[2][i] ^= (*RoundKey)[2][i];
        (*state)[3][i] ^= (*RoundKey)[3][i];
        (*state)[4][i] ^= (*RoundKey)[4][i];
        (*state)[5][i] ^= (*RoundKey)[5][i];
        (*state)[6][i] ^= (*RoundKey)[6][i];
        (*state)[7][i] ^= (*RoundKey)[7][i];
#if defined(SNC_512) || defined(SNC_768)
        // 此块为复合加密,也就是[32 - 63]字节的密钥再次加密
        (*state)[0][i] ^= (*RoundKey)[0][i + 4];
        (*state)[1][i] ^= (*RoundKey)[1][i + 4];
        (*state)[2][i] ^= (*RoundKey)[2][i + 4];
        (*state)[3][i] ^= (*RoundKey)[3][i + 4];
        (*state)[4][i] ^= (*RoundKey)[4][i + 4];
        (*state)[5][i] ^= (*RoundKey)[5][i + 4];
        (*state)[6][i] ^= (*RoundKey)[6][i + 4];
        (*state)[7][i] ^= (*RoundKey)[7][i + 4];
#endif // #if defined(SNC_512) || defined(SNC_768)
#if defined(SNC_768)
        // 此块为复合加密,也就是[64 - 95]字节的密钥再次加密
        (*state)[0][i] ^= (*RoundKey)[0][i + 8];
        (*state)[1][i] ^= (*RoundKey)[1][i + 8];
        (*state)[2][i] ^= (*RoundKey)[2][i + 8];
        (*state)[3][i] ^= (*RoundKey)[3][i + 8];
        (*state)[4][i] ^= (*RoundKey)[4][i + 8];
        (*state)[5][i] ^= (*RoundKey)[5][i + 8];
        (*state)[6][i] ^= (*RoundKey)[6][i + 8];
        (*state)[7][i] ^= (*RoundKey)[7][i + 8];
#endif // #if defined(SNC_768)
    }

    // 执行行混合函数与列移位函数
    SNC_RowsMix(state);
    SNC_ColumnShift(state);
}

static snVoid SNC_InvCipher(sncState_t *state, sncState_t *RoundKey)
{
    register sn_u32 i;

    // 执行逆列移位函数与逆行混合函数
    SNC_InvColumnShift(state);
    SNC_InvRowsMix(state);

    for(i = 0; i < SNC_NK; ++i) {
#if defined(SNC_768)
        // 此块为复合解密,也就是[64 - 95]字节的密钥解密
        (*state)[0][i] ^= (*RoundKey)[0][i + 8];
        (*state)[1][i] ^= (*RoundKey)[1][i + 8];
        (*state)[2][i] ^= (*RoundKey)[2][i + 8];
        (*state)[3][i] ^= (*RoundKey)[3][i + 8];
        (*state)[4][i] ^= (*RoundKey)[4][i + 8];
        (*state)[5][i] ^= (*RoundKey)[5][i + 8];
        (*state)[6][i] ^= (*RoundKey)[6][i + 8];
        (*state)[7][i] ^= (*RoundKey)[7][i + 8];
#endif // #if defined(SNC_768)
#if defined(SNC_512) || defined(SNC_768)
        // 此块为复合解密,也就是[32 - 63]字节的密钥再次解密
        (*state)[0][i] ^= (*RoundKey)[0][i + 4];
        (*state)[1][i] ^= (*RoundKey)[1][i + 4];
        (*state)[2][i] ^= (*RoundKey)[2][i + 4];
        (*state)[3][i] ^= (*RoundKey)[3][i + 4];
        (*state)[4][i] ^= (*RoundKey)[4][i + 4];
        (*state)[5][i] ^= (*RoundKey)[5][i + 4];
        (*state)[6][i] ^= (*RoundKey)[6][i + 4];
        (*state)[7][i] ^= (*RoundKey)[7][i + 4];
#endif // #if defined(SNC_512) || defined(SNC_768)
        // 此块为基础解密,也就是使用[0 - 31]字节的密钥进行解密
        (*state)[0][i] ^= (*RoundKey)[0][i];
        (*state)[1][i] ^= (*RoundKey)[1][i];
        (*state)[2][i] ^= (*RoundKey)[2][i];
        (*state)[3][i] ^= (*RoundKey)[3][i];
        (*state)[4][i] ^= (*RoundKey)[4][i];
        (*state)[5][i] ^= (*RoundKey)[5][i];
        (*state)[6][i] ^= (*RoundKey)[6][i];
        (*state)[7][i] ^= (*RoundKey)[7][i];
    }

    // 执行块逆置换函数
    SNC_InvSubBytes(state);
}

// CBC模式加密
snVoid SNC_CBC_Encrypt(SNC_ctx *ctx, snByte *buf, snSize_t size)
{
    register snSize_t r;
    register snSize_t i;

    sncState_t *bufState = (sncState_t *)buf;
    sncState_t *ivState = (sncState_t *)ctx->iv;
    size /= SNC_BLOCKLEN;

    for(r = 0; r < SNC_NR; ++r) {
        for(i = 0; i < size; ++i) {
            SNC_XorWithIV((bufState + i), ivState);
            SNC_Cipher((bufState + i), (sncState_t *)ctx->rk[r]);
            ivState = (bufState + i);
        }
    }
}

// CBC模式解密 我干你妈,解密不了啊
// 修复你妈的BUG,操,老子去睡觉了,滚你妈的
snVoid SNC_CBC_Decrypt(SNC_ctx *ctx, snByte *buf, snSize_t size)
{
    register snSize_t r;
    register snSize_t i;

    sncState_t *bufState = (sncState_t *)buf;
    sncState_t *ivState = (sncState_t *)ctx->iv;
    size /= SNC_BLOCKLEN;

    for(r = 0; r < SNC_NR; ++r) {
        for(i = 0; i < size; ++i) {
            SNC_InvCipher((bufState + i), (sncState_t *)ctx->rk[SNC_NR - r - 1]);
            SNC_XorWithIV((bufState + i), ivState);
            ivState = bufState + i;
        }
    }
}

如果你能回答我的问题,再次感谢你!

我试过把多轮加密改成只加密一轮,还是有问题。第一个和第二个密文包可以被解密,但是后面的密文包就像是“以另一种形式再次加密”。
我试过直接使用类似AES加密算法CBC模式的解密过程,还是没用
仔细看了一下维基百科关于CBC模式的解释,但是好像脑子不允许我看懂(?)。
我求助于 ChatGPT、New Bing 和各种搜索引擎,但可能是因为它们还不够聪明,无法给我一个很好的解释。

c encryption aes cbc-mode block-cipher
© www.soinside.com 2019 - 2024. All rights reserved.