AES踩坑

要求:AES192/ECB/PKCS5Padding
服务器端使用JAVA,选择上述加密模式, BlockSize:16字节。
4G模块端使用C,如果照着网上的解释编写与JAVA对应的填充方式,就会出错,无法解码。这是PKCS5和PKCS7的概念混淆导致的。
我的解决方法:
数据长度:length
a:
if(length%16==0)
再填充16个0x10;
b:
if(length%16)
填充16-length%16;
注:为8的时候单独赋0x08,(具体原因不知道)

注:此处C语言实现部分没看是什么填充方式,但是可以加解密,且与AES在线加解密结果一致。

aes.c
//加密
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf, uint32_t length)                        
{
 		 // The next function call encrypts the PlainText with the Key using AES algorithm.
		uintptr_t i; 
		uint8_t cpbuf[16];	
		size_t padding;
		int num = 0;
		num = length%16;	
		padding = 16-(length%16);
		for(i = 0; i < length/16; i++){
			Cipher((state_t*)buf, ctx->RoundKey); 
			buf += AES_BLOCKLEN;		
		}			
		if(num != 0)
		{
			memcpy(cpbuf, buf, length%16);
			if(num %8){
				memset(cpbuf + length%16, padding, 16-length%16);//2021.3.21更改,原先是16-length%8,长度计算错误
			}
			else{
				memset(cpbuf+8, 0x08, 8);
			}
		}
		else{
				memset(cpbuf, 0x10, 16);
		}
		Cipher((state_t*)cpbuf, ctx->RoundKey); 
		memcpy(buf, cpbuf, AES_BLOCKLEN);
}
//解密
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf, uint32_t length)   
{
	  // The next function call decrypts the PlainText with the Key using AES algorithm.
		uintptr_t i; 
		for(i = 0; i < length/16; i++)
		{
			InvCipher((state_t*)buf, ctx->RoundKey);
			buf += AES_BLOCKLEN;
		}
		InvCipher((state_t*)buf, ctx->RoundKey);
}
main.c
int main(void){
		int i;
		struct AES_ctx ctx;
		int datalen = 1;
		int endatalen;
		char key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5};//秘钥
		uint8_t in[] = {0x0E};//待加密数据
		
		endatalen = (datalen/16 + 1)*16;									
		printf("\n______________________加密开始_____________________________\n");									
		printf("原数据:");
		for(i = 0; i < datalen; i++){
			printf("%x ",in[i]);
		}
		printf("\n");
		AES_init_ctx(&ctx, key);//秘钥初始化
		AES_ECB_encrypt(&ctx, in, datalen);//加密			
												
		printf("加密后:");
		for(i = 0; i < endatalen; i++){
			printf("%x ",in[i]);
		}
		printf("\n");
												
		AES_ECB_decrypt(&ctx, in, datalen); //解密            																
		printf("解密后:");
		for(i = 0; i < endatalen; i++){
			printf("%x ",in[i]);
		}
												
		printf("\n");									
		printf("\n_________________________加密结束_____________________________\n");
		return 0;
}
原数据:e 
加密后:11 3a af 4c 8f 7c 74 56 43 47 ad c8 80 63 2d 3d 
解密后:e f f f f f f f f f f f f f f f 

注:解密数据打印了填充的部分,实际应用中可删除

其他信息在AES加密学习笔记中。

踩坑暂时结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值