前言:
今天刚好在系统上增加SM4算法的支持,SM4算法的实现网上你可以搜到很多版本,但是如果你要运用到实际中时,你一定要了解SM4算法填充规则。
正文:
首先,SM4接口大多是以最小单位16Byte进行加解密。因此SM4的密文长度通常是16Byte的倍数。当你待加密数据小于16Byte时,你便需要使用填充算法。
PKCS7填充算法规则:
PKCS7填充单位为16Byte,对于不满16Byte的数据,以【16-数据长度】字符进行填充。其实现算法如下:
int PKCS7(unsigned char *pucData, unsigned long ulDataLen, unsigned char pucPaddingData[16])
{
unsigned char pucPadding = 0;
if(ulDataLen > 16)
{
return -1;
}
pucPadding = 16 - ulDataLen;
memcpy(pucPaddingData, pucData, ulDataLen);
memset(pucPaddingData + ulDataLen, pucPadding, 16 - ulDataLen);
return 0;
}
PKCS5填充算法规则:
PKCS5属于PKCS7填充单位为8Byte,对于不满8Byte的数据,以【8-数据长度】字符进行填充。其实现算法如下:
int PKCS5(unsigned char *pucData, unsigned long ulDataLen, unsigned char pucPaddingData[8])
{
unsigned char pucPadding = 0;
if(ulDataLen > 8)
{
return -1;
}
pucPadding = 8 - ulDataLen;
memcpy(pucPaddingData, pucData, ulDataLen);
memset(pucPaddingData + ulDataLen, pucPadding, 8 - ulDataLen);
return 0;
}
注意事项:
1、如果你使用的是SM4算法,你直接使用PKCS7填充即可,之前我遇到过JAVA的API里写着使用PKCS5,但实际输出结果为PKCS7。
2、如果你使用了填充算法加密数据,如果是PKCS7算法,则待加密数据为16倍数时,待加密数据尾部需要补16位0x10。
3、如果你使用了填充算法加密数据,如果是PKCS5算法,则待加密数据为8倍数时,待加密数据尾部需要补8位0x8。
4、同理解密时,如果确定加密时使用了填充算法,对于解密后的数据,需要将填充数据剔除。