1、对称算法常用补位方式
在使用对称加密算法时,很常见的一种情况是需要对数据进行补位(Padding),以确保数据块的大小适合算法要求。下面,我将介绍一些常用的补位方式:
2、PKCS#7/PKCS#5 补位:
这是最常用的补位方案之一。PKCS#7 是通用的,而 PKCS#5 原本设计用于8字节块的算法(如DES)。
补位规则是将每个补位字节填充为需要添加的字节数。例如,如果数据需要补充5个字节才能达到块的大小,那么这5个字节都将填充为数字05。
#include <stdio.h>
#include <string.h>
void pkcs7_padding(unsigned char *block, int block_size, int input_length)
{
unsigned char padding_value = block_size - (input_length % block_size);
for (int i = input_length; i < input_length + padding_value; i++) {
block[i] = padding_value;
}
}
int main() {
unsigned char data[64] = "Hello, world! This is a PKCS#7 padding example.";
int data_length = strlen((char *)data);
int block_size = 16;
printf("Original data (%d bytes): '%s'\n", data_length, data);
pkcs7_padding(data, block_size, data_length);
int padded_length = data_length + (block_size - (data_length % block_size));
printf("Padded data (%d bytes): ", padded_length);
for (int i = 0; i < padded_length; i++) {
printf("%02x ", data[i]);
}
printf("\n");
return 0;
}
#include <stdio.h>
#include <string.h>
void pkcs5_padding(unsigned char *block, int block_size, int input_length) {
unsigned char padding_value = block_size - (input_length % block_size);
for (int i = input_length; i < input_length + padding_value; i++) {
block[i] = padding_value;
}
}
int main() {
unsigned char data[64] = "Hello, PKCS#5 padding!";
int data_length = strlen((char *)data);
int block_size = 8;
printf("Original data (%d bytes): '%s'\n", data_length, data);
pkcs5_padding(data, block_size, data_length);
int padded_length = data_length + (block_size - (data_length % block_size));
printf("Padded data (%d bytes): ", padded_length);
for (int i = 0; i < padded_length; i++) {
printf("%02x ", data[i]);
}
printf("\n");
return 0;
}
3、ANSI X.923:
在这种补位方式中,除了最后一个补位字节表示补位的数量(如PKCS#7),其余补位字节都填充为00。
例如,如果需要补6个字节,那么补位为 00 00 00 00 00 06。
#include <stdio.h>
#include <string.h>
void ansi_x923_padding(unsigned char *block, int block_size, int input_length) {
unsigned char padding_value = block_size - (input_length % block_size);
for (int i = input_length; i < input_length + padding_value - 1; i++) {
block[i] = 0x00;
}
block[input_length + padding_value - 1] = padding_value;
}
int main() {
unsigned char data[64] = "Hello, ANSI X.923 padding example!";
int data_length = strlen((char *)data);
int block_size = 16;
printf("Original data (%d bytes): '%s'\n", data_length, data);
ansi_x923_padding(data, block_size, data_length);
int padded_length = data_length + (block_size - (data_length % block_size));
printf("Padded data (%d bytes): ", padded_length);
for (int i = 0; i < padded_length; i++) {
printf("%02x ", data[i]);
}
printf("\n");
return 0;
}
4、ISO 10126:
这种补位方式在标准中已不推荐使用,但了解它也有助于对历史数据进行解密。
它与ANSI X.923类似,但在最后一个字节之前的补位使用随机数而非00。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void iso_10126_padding(unsigned char *block, int block_size, int input_length) {
unsigned char padding_value = block_size - (input_length % block_size);
for (int i = input_length; i < input_length + padding_value - 1; i++) {
block[i] = rand() % 256;
}
block[input_length + padding_value - 1] = padding_value;
}
int main() {
srand(time(NULL));
unsigned char data[64] = "Hello, ISO 10126 padding example!";
int data_length = strlen((char *)data);
int block_size = 16;
printf("Original data (%d bytes): '%s'\n", data_length, data);
iso_10126_padding(data, block_size, data_length);
int padded_length = data_length + (block_size - (data_length % block_size));
printf("Padded data (%d bytes): ", padded_length);
for (int i = 0; i < padded_length; i++) {
printf("%02x ", data[i]);
}
printf("\n");
return 0;
}
5、Zero Padding(零补位):
这种方式简单地将数据的末尾用零填充。这种方法可能在解密时无法明确知道补位的确切数量,除非数据原本不可能以零结束。
#include <stdio.h>
#include <string.h>
void zero_padding(unsigned char *block, int block_size, int input_length) {
int padding_needed = block_size - (input_length % block_size);
for (int i = input_length; i < input_length + padding_needed; i++) {
block[i] = 0x00;
}
}
int main() {
unsigned char data[64] = "Hello, Zero Padding example!";
int data_length = strlen((char *)data);
int block_size = 16;
printf("Original data (%d bytes): '%s'\n", data_length, data);
zero_padding(data, block_size, data_length);
int padded_length = data_length + (block_size - (data_length % block_size));
printf("Padded data (%d bytes): ", padded_length);
for (int i = 0; i < padded_length; i++) {
printf("%02x ", data[i]);
}
printf("\n");
return 0;
}
6、Bit Padding:
这种补位方式适用于位操作。它在数据的末尾添加一个1(以二进制表示),然后用0填充至块边界。
#include <stdio.h>
#include <string.h>
void bit_padding(unsigned char *block, int block_size, int input_length) {
int padding_needed = block_size - (input_length % block_size);
block[input_length] = 0x80;
for (int i = input_length + 1; i < input_length + padding_needed; i++) {
block[i] = 0x00;
}
}
int main() {
unsigned char data[64] = "Hello, Bit Padding example!";
int data_length = strlen((char *)data);
int block_size = 16;
printf("Original data (%d bytes): '%s'\n", data_length, data);
bit_padding(data, block_size, data_length);
int padded_length = data_length + (block_size - (data_length % block_size));
printf("Padded data (%d bytes): ", padded_length);
for (int i = 0; i < padded_length; i++) {
printf("%02x ", data[i]);
}
printf("\n");
return 0;
}