我写了一个对称加密算法,其加密过程类似于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
#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
// 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 和各种搜索引擎,但可能是因为它们还不够聪明,无法给我一个很好的解释。