加密填充方式(pkcs5/pkcs7/ISO10126填充/ANSIX923填充/Zeros填充)外部填充

  由于SM2等加密分组方式,每次要求为16byte的时候,需要进行填充,填充的方式有如下:

pkcs5/pkcs7/ISO10126填充/ANSIX923填充/Zeros填充

解释:

pkcs5 是pkcs7的子集,专门用于填充8字节的或者8的倍数,pkcs7可以填充字节为多个字节

pkcs7的定义:

比如字节长度为10:

例子1、如果当前的数据为8,那么需要填充2个字节,填充字节为0x02,0x02,

例子2、如果当前数据为3,那么需要填充7个字节,填充的字节为0x07,0x07,0x07,0x07,0x07,0x07,0x07

例子3、如果当前数据为10,那么再填充10个字节,填充字节为

0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A

解析的时候,就是判断后续是否有连续一样的值,并且值和长度相等。

pkcs5定义:只是限制了长度,如果为8或者16,和pkcs7一样。

ISO10126的定义:

最后一位标识补位位数n,之前补位n-1个随机值

比如说字节长度为10:

例子1:当前长度为7,那么需要填充3个字节,最后一个字节为0x03,前面两个是随机数,如下填充:0x01,0xff, 0x03

ANSIX923填充:

填充最后一个字节为长度,其余的为0

比如说字节长度为10:

例子1:当前数据为4,需要填充6个字节,那么最后一个字节为0x06,其余5个字节为0,填充如下:

0x00,0x00,0x00,0x00,0x00,0x06

zeros填充的定义:

不够用0填充

比如说字节长度为10:

例子1:当前长度为6,那么需要填充4个字节,填充字节为0x00:

0x00,0x00,0x00,0x00

具体实现方式如下:

定义一个填充结构

//add hmy 2023年7月17日14:18:33

//填充类型
#define NONE_PADDING 0    //不填充
#define PKCS5_PADDING 1 //pkcs5 填充
#define PKCS7_PADDING 2 //pkcs7 填充
#define ISO10126_PADDING 3 //ISO10126填充
#define ANSIX923_PADDING 4 //ANSIX923填充
#define ZERO_PADDING 5 //Zeros填充

#define SEC_TRUE 1000 //成功
#define SEC_FALSE 0 //失败

//填充结构

typedef struct str_padding_info{

    U32 PaddingType;//填充类型

    U32 dataLen;//数据长度

    U32 PaddingBit;//填充对齐字节默认16

    U8 dataBuf[255];//缓存消息,255

    U32 bufLen;//缓存消息长度,长度为0~255

}PADDING_INFO, * P_PADDING_INFO;

首先初始化结构:

panding_type 填充类型

panding_bit 填充位数 默认为16

padding_info 填充结构

int pandingInit(u32 panding_type, u32 panding_bit, P_PADDING_INFO padding_info)

具体如下:


//add hmy 2023年7月17日14:18:33
//填充结构初始化
//panding_type 填充类型
//panding_bit 填充位数 默认为16
//padding_info 填充结构
int pandingInit(u32 panding_type, u32 panding_bit, P_PADDING_INFO padding_info){
    if (padding_info != NULL){
        if (panding_type != NONE_PADDING && panding_type != PKCS5_PADDING && panding_type != PKCS7_PADDING && panding_type != ISO10126_PADDING && panding_type != ANSIX923_PADDING &&
            panding_type != ZERO_PADDING ){
            PRINTF("error:pading_type error\n");
            return -1;
        }
        memset(padding_info->dataBuf, 0 ,sizeof(padding_info->dataBuf));
        padding_info->bufLen = 0;
        padding_info->dataLen = 0;
        padding_info->PaddingBit = panding_bit;
        padding_info->PaddingType = panding_type;
    }
    return 0;
}

填充实现:

//add hmy 2023年7月17日14:19:28

//zero填充去除
SEC_BOOL chip_padding_zero_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    int pading_len = 0;
    for (int i = *padingLen - 1; i >= *padingLen - padding_info->PaddingBit; i--){
        if (paddingbuf[i] == 0){
            pading_len++;
        }else {
            break;
        }
    }
    *padingLen =  *padingLen - pading_len;
    memset(paddingbuf + *padingLen, 0, pading_len);
    return SEC_TRUE;
}

//zero填充
SEC_BOOL chip_padding_zero_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
   U8 pading_len = (U8)padding_info->PaddingBit - (padding_info->dataLen % (U8)padding_info->PaddingBit);
    for (int i =0 ; i < pading_len; i++){
        paddingbuf[i] = 0;//产生一个随机数;
    }
    *padingLen = pading_len;
}

//ansix923填充去除
SEC_BOOL chip_padding_ansix923_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    U8 pading_len = paddingbuf[*padingLen - 1];
    U8 pos = 0;

    if (padding_info->PaddingBit < pading_len){
        return SEC_FALSE;
    }

    for (int i = *padingLen- 2; i >= *padingLen - pading_len ; i--){
        if (paddingbuf[i] == 0){
            pos++;
        }else {
            break;
        }
    }
    PRINTF("ansix923 decode pos:%d, pading_len:%d\n",pos, padingLen);
    if (pos != pading_len - 1){
        return SEC_FALSE;
    }

    *padingLen =  *padingLen - pading_len;
    memset(paddingbuf + *padingLen, 0, pading_len);
    return SEC_TRUE;
}
//ansix923填充
SEC_BOOL chip_padding_ansix923_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    U8 pading_len = (U8)padding_info->PaddingBit - (padding_info->dataLen % (U8)padding_info->PaddingBit);
    for (int i =0 ; i < pading_len - 1; i++){
        paddingbuf[i] = 0;//产生一个随机数;
    }
    paddingbuf[pading_len- 1] = pading_len;
    *padingLen = pading_len;
    return SEC_TRUE;
}

//iso10126 填充去除
SEC_BOOL chip_padding_iso10126_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    U8 pading_len = paddingbuf[*padingLen - 1];
    U8 pos = 0;
    
    if (padding_info->PaddingBit < pading_len){
        return SEC_FALSE;
    }

    *padingLen =  *padingLen - pading_len;
    memset(paddingbuf + *padingLen, 0, pading_len);

    return SEC_TRUE;
}

//iso10126 填充
SEC_BOOL chip_padding_iso10126_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    U8 pading_len = (U8)padding_info->PaddingBit - (padding_info->dataLen % (U8)padding_info->PaddingBit);

    srand(time(nullptr));//设置随机数种子
    
    for (int i =0 ; i < pading_len - 1; i++){
        paddingbuf[i] = (U8)rand();//产生一个随机数;
    }
    paddingbuf[pading_len- 1] = pading_len;
    *padingLen = pading_len;
    return SEC_TRUE;
}

//PKCS#5填充去除
SEC_BOOL chip_padding_pkcs5_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    U8 pading_len = paddingbuf[*padingLen - 1];
    U8 pos = 0;
    if (8 < pading_len){
        return SEC_FALSE;
    }
    for (int i = *padingLen - 1; i >= *padingLen - pading_len; i--){
        if (paddingbuf[i] == pading_len){
            pos++;
        }else {
            break;
        }
    }
    if (pos != pading_len){
        return SEC_FALSE;
    }
    *padingLen =  *padingLen - pading_len;
    memset(paddingbuf + *padingLen, 0, pading_len);
    return SEC_TRUE;
}
//pkcs#5填充
SEC_BOOL chip_padding_pkcs5_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    U8 pading_len = (U8)8 - (padding_info->dataLen % 8);
    
    for (int i =0 ; i < pading_len; i++){
        paddingbuf[i] = pading_len;
    }
    *padingLen = pading_len;
    return SEC_TRUE;
}

//PKCS#7填充去除
SEC_BOOL chip_padding_pkcs7_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    U8 pading_len = paddingbuf[*padingLen - 1];
    U8 pos = 0;

    if (padding_info->PaddingBit < pading_len){
        PRINTF("padding_pkcs7_decode bit:%d  pading_len:%d\n",padding_info->PaddingBit, pading_len);
        return SEC_FALSE;
    }
    for (int i = *padingLen - 1; i >= *padingLen - pading_len; i--){
        if (paddingbuf[i] == pading_len){
            pos++;
        }else {
            break;
        }
    }
    //PRINTF("pkcs7 pos:%d  pading_len:%d\n",pos, pading_len);
    if (pos != pading_len){
        PRINTF("error: pkcs7 pos:%d  pading_len:%d\n",pos, pading_len);
        return SEC_FALSE;
    }
    *padingLen =  *padingLen - pading_len;
    memset(paddingbuf + *padingLen, 0, pading_len);

    return SEC_TRUE;
}

//PKCS#7填充
SEC_BOOL chip_padding_pkcs7_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    U8 pading_len = (U8)padding_info->PaddingBit - (padding_info->dataLen % (U8)padding_info->PaddingBit);
    for (int i =0 ; i < pading_len; i++){
        paddingbuf[i] = pading_len;
    }
    *padingLen = pading_len;
    return SEC_TRUE;
}

/**
 *  填充处理
 * [in] padding_info 填充结构
 * [out] paddingbuf 输出填充数据
 * [out] padingLen 输出填充长度
*/
SEC_BOOL chip_padding_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    switch(padding_info->PaddingType){
        case NONE_PADDING:
        return SEC_FALSE;
        break;
        case PKCS5_PADDING:
            return chip_padding_pkcs5_encode(padding_info, paddingbuf, padingLen);
        break;
        case PKCS7_PADDING:
            PRINTF("pkcs7 padding\n");
            return chip_padding_pkcs7_encode(padding_info, paddingbuf, padingLen);
        break;
        case ISO10126_PADDING:
            return chip_padding_iso10126_encode(padding_info, paddingbuf, padingLen);
        break;
        case ANSIX923_PADDING:
            return chip_padding_ansix923_encode(padding_info, paddingbuf, padingLen);
        break;
        case ZERO_PADDING:
            return chip_padding_zero_encode(padding_info, paddingbuf, padingLen);
        break;

    }
    return SEC_FALSE;
}

/**
 *  填充去除处理
 * [in] padding_info 填充结构
 * [out] paddingbuf 输出填充数据
 * [out] padingLen 输出填充长度
*/
SEC_BOOL chip_padding_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){
    switch(padding_info->PaddingType){
        case NONE_PADDING:
        return SEC_FALSE;
        break;
        case PKCS5_PADDING:
            return chip_padding_pkcs5_decode(padding_info, paddingbuf, padingLen);
        break;
        case PKCS7_PADDING:
            return chip_padding_pkcs7_decode(padding_info, paddingbuf, padingLen);
        break;
        case ISO10126_PADDING:
            return chip_padding_iso10126_decode(padding_info, paddingbuf, padingLen);
        break;
        case ANSIX923_PADDING:
            return chip_padding_ansix923_decode(padding_info, paddingbuf, padingLen);
        break;
        case ZERO_PADDING:
            return chip_padding_zero_decode(padding_info, paddingbuf, padingLen);
        break;
        default:
        PRINTF("pading encode type error\n");
        return SEC_FALSE;

    }
    return SEC_FALSE;
}

调用方式,这里给示例调用一次的方式



//一次填充
int main(){
	char data[8] = {'1','2','3','4','5','6','7','8'};
	int dataLen = 8;
	char padding_msg = NULL;
	int padding_len = 0;
	
 	PADDING_INFO padding_info = {0};
	if (pandingInit(PKCS7_PADDING , 16, &padding_info) < 0){
		printf("pandingInit error\n");
		return -1;
	}
	
	padding_info->dataLen = dataLen;
	padding_len =  padding_info->dataLen + padding_info->PaddingBit;
	padding_msg = (char *)malloc(msg_len * sizeof(char));
	if (padding_msg == NULL){
		printf("error: malloc error\n");
		return -1;
	}
	//填充
	if (SEC_TRUE != chip_padding_encode(&padding_info, padding_msg + padding_info->dataLen, &msg_len)){
		printf("error: padding error\n");
		free(pmsg_in);
		return -1;
	}
	memcpy(padding_msg, data, dataLen);
    msg_len = msg_len + dataLen;
	
	printf("fill data:\n");
	for (int i = 0; i < msg_len; i++){
		printf("%02X ",padding_msg[i]);
	}
	printf("\n");
	if (pandingInit(PKCS7_PADDING , 16, &padding_info) < 0){
		printf("pandingInit error\n");
		free(pmsg_in);
		return -1;
	}
	
	padding_info->dataLen = msg_len;
    padding_info->bufLen = 0;
	if (SEC_TRUE != chip_padding_decode(&padding_info, padding_msg, &msg_len)){
		printf("decode error\n");
		free(pmsg_in);
		return -1;
	}
	printf("src data:\n");
	for (int i = 0; i < msg_len; i++){
		printf("%02X ",padding_msg[i]);
	}
	printf("\n");
	
	free(pmsg_in);
	return 0;
}

数据量大的方式,多次填充的方式,那么就需要借助里面的缓冲区了,每次都得判断是否为填充字节倍数,如果不够那么需要截取后部分存储在dataBuf里面,下一包的时候拼接在前面,在最后结束一包的时候添加上去。

本来多包编解码填充也是可以封装的,但是够用了就没有封装,自己和逻辑业务放一起了,这里简单调用解释下

其实就是借用了结构的缓冲区,每次进来的数据是否为对齐字节的倍数,如果是倍数那么不需要处理,如果不是,那么需要把多余的数据放入到填充里面,下一次进来的时候,把数据拼接到之前的前面再查询



//多次填充
int main(){
	char data[24] = {0};
	int dataLen = 24;
	int offset = 0;
	char padding_msg[16] = {0};
	int padding_len = 0;
	
	
	for (int i = 0;i < 24; i++){
		data[i] = (char)('0'+(i % 9));
	}
 	PADDING_INFO padding_info = {0};
	if (pandingInit(PKCS7_PADDING , 16, &padding_info) < 0){
		printf("pandingInit error\n");
		return -1;
	}
	
	//例如:第一次填充 2个字节
	dataLen = 2;
	if (dataLen < padding_info->PaddingBit){
		padding_info->bufLen = dataLen;
		memcpy(padding_info->dataBuf,data + offset,dataLen);
		padding_info->bufLen = dataLen;
	}
	offset+= dataLen;
	
	//例如:第二次再填充3个字节
	dataLen = 3;
	if (dataLen + padding_info->bufLen < padding_info->PaddingBit){
		padding_info->bufLen = dataLen;
		memcpy(padding_info->dataBuf + padding_info->bufLen,data + offset,dataLen);
		padding_info->bufLen += dataLen;
	}
	offset+= dataLen;
	
	
	//例如:第三次填充14个字节,这个时候总数为17个字节了,大于对齐字节了,我这里不做通用性判断了,到时候自己实现的额时候
	dataLen = 14;
	if (dataLen + padding_info->bufLen >= padding_info->PaddingBit && padding_info->bufLen > 0){
	
		//先把填充结构缓存部分拿出来
		memcpy(padding_msg, padding_info->dataBuf, padding_info->bufLen);
		padding_len = padding_info->bufLen;
		padding_info->bufLen = 0;
	
		//再添加数据部分凑成对齐字节的16字节
		memcpy(padding_msg + padding_len, data + offset, padding_info->PaddingBit - padding_len);

		//把需要添加的剩余字节继续放入到字段里面
		memcpy(padding_info->dataBuf,data + offset + (padding_info->PaddingBit - padding_len),dataLen - (padding_info->PaddingBit- padding_len));
		padding_info->bufLen =dataLen - (padding_info->PaddingBit- padding_len);
	
		padding_len += padding_info->PaddingBit - padding_len;
		
		//这个时候已经满了对齐字节,可以padding_msg 可以用来处理编码啥的
	}
	offset += dataLen;
	
	

	//例如最后一包:填充剩余6个字节
	dataLen = 6;
	if (dataLen + padding_info->bufLen < padding_info->PaddingBit){
		padding_info->bufLen = dataLen;
		memcpy(padding_info->dataBuf + padding_info->bufLen,data + offset,dataLen);
		padding_info->bufLen += dataLen;
	}
	offset += dataLen;
	
	//最后一包
	dataLen = 6;
	if (padding_info->bufLen > 0){
		//先把填充结构缓存部分拿出来
		memcpy(padding_msg, padding_info->dataBuf, padding_info->bufLen);
		padding_len = padding_info->bufLen;
		padding_info->bufLen = 0;
		
		memcpy(padding_msg + padding_len, data + oofset, dataLen);
		padding_len+= dataLen;
	}
	
	padding_info->dataLen = padding_len;
	padding_len = 16;
	//填充
	if (SEC_TRUE != chip_padding_encode(&padding_info, padding_msg + padding_info->dataLen, &padding_len)){
		printf("error: padding error\n");
		free(pmsg_in);
		return -1;
	}
	padding_len += padding_info->dataLen;
	printf("fill data:\n");
	for (int i = 0; i < padding_len; i++){
		printf("%02X ",padding_msg[i]);
	}
	printf("\n");
	if (pandingInit(PKCS7_PADDING , 16, &padding_info) < 0){
		printf("pandingInit error\n");
		free(pmsg_in);
		return -1;
	}
	
	return 0;
}

你可能感兴趣的:(spring,java,后端)