对称算法常用补位方式详解(二)

1、对称算法常用补位方式

在使用对称加密算法时,很常见的一种情况是需要对数据进行补位(Padding),以确保数据块的大小适合算法要求。下面,我将介绍一些常用的补位方式:

2、PKCS#7/PKCS#5 补位:

这是最常用的补位方案之一。PKCS#7 是通用的,而 PKCS#5 原本设计用于8字节块的算法(如DES)。
补位规则是将每个补位字节填充为需要添加的字节数。例如,如果数据需要补充5个字节才能达到块的大小,那么这5个字节都将填充为数字05。
//PKCS#7补位示例:
	#include <stdio.h>
	#include <string.h>

// 函数:PKCS#7补位
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);

    // 假定块大小为16字节
    int block_size = 16;

    // 打印原始数据
    printf("Original data (%d bytes): '%s'\n", data_length, data);

    // 应用PKCS#7补位
    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;
}
//PKCS#5补位示例
#include <stdio.h>
#include <string.h>

// 函数:PKCS#5补位
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);

    // 假定块大小为8字节
    int block_size = 8;

    // 打印原始数据
    printf("Original data (%d bytes): '%s'\n", data_length, data);

    // 应用PKCS#5补位
    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>

// 函数:ANSI X.923补位
void ansi_x923_padding(unsigned char *block, int block_size, int input_length) {
    // 计算需要填充的字节数
    unsigned char padding_value = block_size - (input_length % block_size);
    // 填充0到最后一个字节之前
    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);

    // 假定块大小为16字节
    int block_size = 16;

    // 打印原始数据
    printf("Original data (%d bytes): '%s'\n", data_length, data);

    // 应用ANSI X.923补位
    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>

// 函数:ISO 10126补位
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;  // 生成0到255之间的随机数
    }
    // 最后一个补位字节是补位长度
    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);

    // 假定块大小为16字节
    int block_size = 16;

    // 打印原始数据
    printf("Original data (%d bytes): '%s'\n", data_length, data);

    // 应用ISO 10126补位
    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>

// 函数:Zero Padding 补位
void zero_padding(unsigned char *block, int block_size, int input_length) {
    // 计算需要填充的字节数
    int padding_needed = block_size - (input_length % block_size);
    // 填充0到数据末尾
    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);

    // 假定块大小为16字节
    int block_size = 16;

    // 打印原始数据
    printf("Original data (%d bytes): '%s'\n", data_length, data);

    // 应用Zero Padding
    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>

// 函数:Bit Padding 补位
void bit_padding(unsigned char *block, int block_size, int input_length) {
    // 计算需要填充的字节数
    int padding_needed = block_size - (input_length % block_size);
    // 首先填充一个0x80(二进制的10000000),表示补位开始
    block[input_length] = 0x80;
    // 填充0直到块的边界
    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);

    // 假定块大小为16字节
    int block_size = 16;

    // 打印原始数据
    printf("Original data (%d bytes): '%s'\n", data_length, data);

    // 应用Bit Padding
    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;
}
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值