异或运算:(B ^ A) ^ A = B ^ 0 = B
根据这个规律可设计出简单加密算法。
B为原始数据,A为密钥。
B与A进行异或得到密文。
将密文与A进行异或可以得到明文B。
对于不同的数据,有的数据可能需要加密,有的无须加密。不同数据之前可能采用的密钥不同。
定义结构体:
typedef struct _CIPHER {
u32 cipher_code; ///>解密key
u8 cipher_enable; ///>解密读使能
} CIPHER;
使用32位表示密钥,8位表示是否使能加解密。
这里可以根据不同数据来初始化密钥以及是否使能加密操作:
void cipher_init(CIPHER *pcipher, u32 key)
{
pcipher->cipher_code = key;//key初始化
cipher_ctl(pcipher, 0);//不使能解密
}
初始化后,默认是不进行加解密的。
通过控制函数来进行加解密的配置:
1表示使能加密
0表示禁止加密
static void cipher_ctl(CIPHER *pcipher, u8 ctl)
{
pcipher->cipher_enable = ctl;
}
该函数提供关闭加密功能:
void cipher_close(CIPHER *pcipher)
{
cipher_ctl(pcipher, 0);//不使能解密
}
这里采用按照4字节对齐的方式进行加解密。
addr % 4 = 0,使用cipher_code[0]进行加解密;
addr % 4 = 1,使用cipher_code[1]进行加解密;
addr % 4 = 2,使用cipher_code[2]进行加解密;
addr % 4 = 3,使用cipher_code[3]进行加解密。
宏定义,4字节对齐
#define ALIN_SIZE 4
解密函数:
void cryptanalysis_buff(CIPHER *pcipher, void *buf, u32 faddr, u32 len)
pcipher:加解密结构体指针,包含密钥、加密使能标志。
buf:需要解密的数据。
faddr:数据存储的首地址。
len:需要解密的数据长度,单位字节。
由于是按照4字节对齐的方式进行加解密,因此数据头部、尾部可能存在没有对齐的数据。使用下面两个变量来表示头尾没有对齐的数据字节个数:
u8 head_rem;//头部未对齐的字节数,多出来的字节
u8 tail_rem;//尾部对齐未满4字节的字节数,多出来的字节
定义一个指针来指向密钥,便于后面使用密钥。
u8 *cipher_code;
cipher_code = (u8 *)&pcipher->cipher_code;//密钥
首先需要判断,如果没有使能加解密,则直接返回即可,无须进行解密操作。
if (!pcipher->cipher_enable) {//没有使能解密,则直接返回
return;
}
文件加密采用4字节对齐方式
地址0000使用key0加密
地址0001使用key1加密
地址0002使用key2加密
地址0003使用key3加密
如果传入的buf不是4字节对齐的,则需要先把头部未对齐的字节解密
再使用for循环将中间对齐的字节解密
最后将尾部对齐的未满4字节的数据字节解密
这里根据地址,首先计算出头部没有对齐的字节数:
4 - (0 - 3) = 1-4
head_rem = ALIN_SIZE - (faddr % ALIN_SIZE);//范围1-4
if (head_rem == ALIN_SIZE) {//如果为4表示是对齐的
head_rem = 0;
}
通过上述处理,head_rem为0-3,表示未对齐字节个数
即addr到所在4字节对齐区域尾地址字节个数
当总长度len范围为1-2时,len可能小于head_rem,即需要处理的数据字节数小于4个,且未对齐
head_rem就为len个数据,如len为1,head_rem为2,表示此时仅需要处理1个数据即可
if (head_rem > len) {
head_rem = len;
}
需要处理的数据长度比头部未对齐的数据个数多,则使用地址加数据长度对4求余得到尾部的未对齐字节数。
如果需要处理的数长度比头部未对齐的数据个数少,此时len个数据都在一个4字节地址对齐的空间中,没有尾部没对齐字节数。
if (len - head_rem) {//len大于head_rem
tail_rem = (faddr + len) % ALIN_SIZE;//尾部对齐未满4字节的个数
} else {
tail_rem = 0;//len小于等于head_rem则说明无须处理尾部未对齐,此时数据在一个4字节对齐的地址空间中
}
如果head_rem为0,则不进行for循环
如果head_rem为1,则只处理1字节,即buf[0],key为key[3]
如果head_rem为2,则只处理2字节,即buf[1-0],key为key[3-2]
如果head_rem为3,则只处理3字节,即buf[2-0],key为key[3-1]
for (i = head_rem; i > 0; i--) {
buf_1b_ali[i - 1] ^= cipher_code[j--];
}
上述将头部进行了解密操作。
对于中间对齐的部分,使用for循环即可进行解密。
buf_1b_ali = buf;
buf_1b_ali = (u8 *)(buf_1b_ali + head_rem);//指向第一个4字节对齐的首地址
len_ali = len - head_rem - tail_rem;//所有对齐区域字节数
for (i = 0; i < (len_ali / 4); i++) {
buf_1b_ali[0 + i * 4] ^= cipher_code[0];//4字节对齐第一个字节,对应key[0]
buf_1b_ali[1 + i * 4] ^= cipher_code[1];//4字节对齐第二个字节,对应key[1]
buf_1b_ali[2 + i * 4] ^= cipher_code[2];//4字节对齐第三个字节,对应key[2]
buf_1b_ali[3 + i * 4] ^= cipher_code[3];//4字节对齐第四个字节,对应key[3]
}
尾部数据解密类似头部,不过key从0开始。
buf_1b_ali = buf;
buf_1b_ali += len - tail_rem;//处理尾巴处数据
j = 0;
for (i = 0 ; i < tail_rem; i++) {
buf_1b_ali[i] ^= cipher_code[j++];//尾巴数据从key[0]开始
}
这里仅提供解密操作流程。首先对头部未对齐数据进行解密,再对中间对齐的数据进行解密,最后对尾部未对齐数据进行解密。
3954



被折叠的 条评论
为什么被折叠?



