PKCS7填充标准代码--C语言实现
本文轉自:https://blog.csdn.net/IOT2017/article/details/84141461
在AES加密算法中,若加密數據不是16bytes的整倍數,則需要按照一定標準對數據進行填充,使其滿足 DataSize % 16 = 0。本文是根據PKCS7標準進行數據填充。
PKCS7 填充標準摘要
PKCS5Padding和PKCS7Padding都是密鑰的一種填充方式,即當密鑰長度不足時的一種密鑰填充方式。PKCS5Padding的填充方式為當密鑰長度不足時,缺幾位補幾個0,eg.針對AES128,如果密鑰為“1234567890”一共10位,缺6位,采用PKCS5Padding方式填充之后的密鑰為“1234567890000000”,補了6個0.PKCS7Padding的填充方式為當密鑰長度不足時,缺幾位補幾個幾,eg.對于AES128,如果密鑰為”1234567890”一共10位,缺6位,采用PKCS7Padding方式填充之后的密鑰為“1234567890666666”。
?
源碼
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h> ? ? //使用memset函數要包含此庫
#define MAXLEN ?1024?? ?// 定義一次性處理數據的最大size
/**
?* 加密明文如果不是16byte整倍數,則根據PKCS7標準填充至16byte整倍數
?* 參數 p:明文的字符串數組。
?* 參數 plen:明文長度
?* 返回padding后的明文長度
?*/
?int PKCS7Padding(char *p, int plen)
?{
?? ?int plen_after_Padding, remain, padding_num;
?? ?char padding_value;
?? ?if(plen % 16 == 0)
?? ?{
? ? ? ? plen_after_Padding = plen;
? ? ? ? exit(0);
? ? }
?? ?if(plen == 0)
?? ?{
?? ??? ?printf("加密數據為空!\n");
? ? ? ? exit(0);
?? ?}
?? ?if( plen % 16 != 0)
?? ?{
?? ??? ?remain = plen % 16;
?? ??? ?switch (remain)
?? ??? ?{
?? ??? ? ? ?case 1:
?? ??? ??? ??? ?padding_num = 15;
?? ??? ??? ??? ?padding_value = 0x0F;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 2:
?? ??? ??? ??? ?padding_num = 14;
?? ??? ??? ??? ?padding_value = 0x0E;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 3:
?? ??? ??? ??? ?padding_num = 13;
?? ??? ??? ??? ?padding_value = 0x0D;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 4:
?? ??? ??? ??? ?padding_num = 12;
?? ??? ??? ??? ?padding_value = 0x0C;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 5:
?? ??? ??? ??? ?padding_num = 11;
?? ??? ??? ??? ?padding_value = 0x0B;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 6:
?? ??? ??? ??? ?padding_num = 10;
?? ??? ??? ??? ?padding_value = 0x0A;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 7:
?? ??? ??? ??? ?padding_num = 9;
?? ??? ??? ??? ?padding_value = 0x09;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 8:
?? ??? ??? ??? ?padding_num = 8;
?? ??? ??? ??? ?padding_value = 0x08;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 9:
?? ??? ??? ??? ?padding_num = 7;
?? ??? ??? ??? ?padding_value = 0x07;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 10:
?? ??? ??? ??? ?padding_num = 6;
?? ??? ??? ??? ?padding_value = 0x06;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 11:
?? ??? ??? ??? ?padding_num = 5;
?? ??? ??? ??? ?padding_value = 0x5;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 12:
?? ??? ??? ??? ?padding_num = 4;
?? ??? ??? ??? ?padding_value = 0x04;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 13:
?? ??? ??? ??? ?padding_num = 3;
?? ??? ??? ??? ?padding_value = 0x03;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 14:
?? ??? ??? ??? ?padding_num = 2;
?? ??? ??? ??? ?padding_value = 0x02;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 15:
?? ??? ??? ??? ?padding_num = 1;
?? ??? ??? ??? ?padding_value = 0x01;
?? ??? ??? ??? ?break;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? break;
?? ??? ?}
?? ?}
? ? plen_after_Padding = plen + padding_num;
?? ?for(int i = plen; i < plen_after_Padding; i++)
?? ?{
?? ??? ?p[i] = padding_value;
?? ?}
?? ?p[plen_after_Padding] = '\0';?? ?//明文原來就是以'\0'結尾,但是被填充沖掉了,所以填充完成后需要在數據最后加上'\0'
?? ?return plen_after_Padding;
?}
?/**
? * 從命令行獲取數據并將結尾換行符替換為'\0'
? */
?void getString(char *str, int len)
?{
? ? int slen = read(0, str, len);
? ? for(int i = 0; i < slen; i++)
? ? {
? ? ? ? if(str[i] == '\n')
? ? ? ? {
? ? ? ? ? ? str[i] = '\0';
? ? ? ? ? ? break;
? ? ? ? }
? ? }
}
int main()
{
? ? int plen, after_padding_plen;
? ? char *p;
? ? p = (char*)malloc(MAXLEN*(sizeof(char*)));?? ??? ?//申請一塊內存用來存放明文數據
? ? memset(p,0,MAXLEN);
? ? printf("請輸入一串字符:\n");
? ? getString(p,MAXLEN);
? ? for(plen = 0; p[plen] != '\0'; plen++ ); ? ?//獲取輸入明文數據字符串長度(不包含換行符)
? ? printf("輸入明文長度為:%d 個字節\n", plen);
? ??
? ? after_padding_plen = PKCS7Padding(p,plen);
? ? printf("按照PKCS7標準填充后的明文長度為:%d 個字節\n", after_padding_plen);
? ? for(int i =0; p[i]!='\0';i++)
? ? {
? ? ? ? printf("p[%d] = 0x%x\n",i,p[i]);
? ? }
?? ?free(p);?? ??? ?//釋放內存
}
?
解密數據cutting填充數據
/**
?* 將解密后的明文填充數據去掉,還原數據
?* int PKCS7Cutting(char *p, int plen)
?* 參數 p:解密后明文的字符串數組。
?* 參數 plen:解密后明文長度
?* 返回cutting后的明文長度
?*/
?int ?PKCS7Cutting(char *p, int plen)
?{
? ? int plen_after_cutting;
? ? if(p[plen-1] == 0x01)
? ? {
? ? ? ? plen_after_cutting = plen -1;
? ? }
? ? else if(p[plen-1] == 0x02)
? ? {
? ? ? ? if(p[plen-2] == 0x02)
? ? ? ? ? ? plen_after_cutting = plen -2;
? ? }
? ? else if(p[plen-1] == 0x03)
? ? {
? ? ? ? if((p[plen-2] == 0x03) && (p[plen-3] == 0x03))
? ? ? ? ? ? plen_after_cutting = plen -3;
? ? }
? ? else if(p[plen-1] == 0x04)
? ? {
? ? ? ? if((p[plen-2] == 0x04) && (p[plen-3] == 0x04) && (p[plen-4] == 0x04))
? ? ? ? ? ? plen_after_cutting = plen -4;
? ? }
? ? else if(p[plen-1] == 0x05)
? ? {
? ? ? ? if((p[plen-2] == 0x05) && (p[plen-3] == 0x05) && (p[plen-4] == 0x05) && (p[plen-5] == 0x05))
? ? ? ? ? ? plen_after_cutting = plen -5;
? ? }
? ? else if(p[plen-1] == 0x06)
? ? {
? ? ? ? if((p[plen-2] == 0x06) && (p[plen-3] == 0x06) && (p[plen-4] == 0x06) && (p[plen-5] == 0x06) && (p[plen-6] == 0x06))
? ? ? ? ? ? plen_after_cutting = plen -6;
? ? }
? ? else if(p[plen-1] == 0x07)
? ? {
? ? ? ? if((p[plen-2] == 0x07) && (p[plen-3] == 0x07) && (p[plen-4] == 0x07) && (p[plen-5] == 0x07) && (p[plen-6] == 0x07) && (p[plen-7] == 0x07))
? ? ? ? ? ? plen_after_cutting = plen -7;
? ? }
? ? else if(p[plen-1] == 0x08)
? ? {
? ? ? ? if((p[plen-2] == 0x08) && (p[plen-3] == 0x08) && (p[plen-4] == 0x08) && (p[plen-5] == 0x08) && (p[plen-6] == 0x08) && (p[plen-7] == 0x08) && (p[plen-8] == 0x08))
? ? ? ? ? ? plen_after_cutting = plen -8;
? ? }
? ? else if(p[plen-1] == 0x09)
? ? {
? ? ? ? if((p[plen-2] == 0x09) && (p[plen-3] == 0x09) && (p[plen-4] == 0x09) && (p[plen-5] == 0x09) && (p[plen-6] == 0x09) && (p[plen-7] == 0x09) && (p[plen-8] == 0x09) && (p[plen-9] == 0x09))
? ? ? ? ? ? plen_after_cutting = plen -9;
? ? }
? ? else if(p[plen-1] == 0x0A)
? ? {
? ? ? ? if((p[plen-2] == 0x0A) && (p[plen-3] == 0x0A) && (p[plen-4] == 0x0A) && (p[plen-5] == 0x0A) && (p[plen-6] == 0x0A) && (p[plen-7] == 0x0A) && (p[plen-8] == 0x0A) && (p[plen-9] == 0x0A) && (p[plen-10] == 0x0A))
? ? ? ? ? ? plen_after_cutting = plen -10;
? ? }
? ? else if(p[plen-1] == 0x0B)
? ? {
? ? ? ? if((p[plen-2] == 0x0B) && (p[plen-3] == 0x0B) && (p[plen-4] == 0x0B) && (p[plen-5] == 0x0B) && (p[plen-6] == 0x0B) && (p[plen-7] == 0x0B) && (p[plen-8] == 0x0B) && (p[plen-9] == 0x0B) && (p[plen-10] == 0x0B) && (p[plen-11] == 0x0B))
? ? ? ? ? ? plen_after_cutting = plen -11;
? ? }
? ? else if(p[plen-1] == 0x0C)
? ? {
? ? ? ? if((p[plen-2] == 0x0C) && (p[plen-3] == 0x0C) && (p[plen-4] == 0x0C) && (p[plen-5] == 0x0C) && (p[plen-6] == 0x0C) && (p[plen-7] == 0x0C) && (p[plen-8] == 0x0C) && (p[plen-9] == 0x0C) && (p[plen-10] == 0x0C) && (p[plen-11] == 0x0C) && (p[plen-12] == 0x0C))
? ? ? ? ? ? plen_after_cutting = plen -12;
? ? }
? ? else if(p[plen-1] == 0x0D)
? ? {
? ? ? ? if((p[plen-2] == 0x0D) && (p[plen-3] == 0x0D) && (p[plen-4] == 0x0D) && (p[plen-5] == 0x0D) && (p[plen-6] == 0x0D) && (p[plen-7] == 0x0D) && (p[plen-8] == 0x0D) && (p[plen-9] == 0x0D) && (p[plen-10] == 0x0D) && (p[plen-11] == 0x0D) && (p[plen-12] == 0x0D) && (p[plen-13] == 0x0D))
? ? ? ? ? ? plen_after_cutting = plen -13;
? ? }
? ? else if(p[plen-1] == 0x0E)
? ? {
? ? ? ? if((p[plen-2] == 0x0E) && (p[plen-3] == 0x0E) && (p[plen-4] == 0x0E) && (p[plen-5] == 0x0E) && (p[plen-6] == 0x0E) && (p[plen-7] == 0x0E) && (p[plen-8] == 0x0E) && (p[plen-9] == 0x0E) && (p[plen-10] == 0x0E) && (p[plen-11] == 0x0E) && (p[plen-12] == 0x0E) && (p[plen-13] == 0x0E) && (p[plen-14] == 0x0E))
? ? ? ? ? ? plen_after_cutting = plen -14;
? ? }
? ? else if(p[plen-1] == 0x0F)
? ? {
? ? ? ? if((p[plen-2] == 0x0F) && (p[plen-3] == 0x0F) && (p[plen-4] == 0x0F) && (p[plen-5] == 0x0F) && (p[plen-6] == 0x0F) && (p[plen-7] == 0x0F) && (p[plen-8] == 0x0F) && (p[plen-9] == 0x0F) && (p[plen-10] == 0x0F) && (p[plen-11] == 0x0F) && (p[plen-12] == 0x0F) && (p[plen-13] == 0x0F) && (p[plen-14] == 0x0F) && (p[plen-15] == 0x0F))
? ? ? ? ? ? plen_after_cutting = plen -15;
? ? }
? ? else
? ? {
? ? ? ? plen_after_cutting = plen;
? ? }
? ? return plen_after_cutting;
?}
總結
以上是生活随笔為你收集整理的PKCS7填充标准代码--C语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编译器编译16bit单片机程序对数组da
- 下一篇: C# ListView控件显示表格(自适