国密算法sm4 CBC模式加解密

一.什么是CBC模式?
CBC模式的全称是Cipher Block Chaining模式(密文分组链接模式),之所以叫这个名字,是因为密文分组像链条一样相互连接在一起。
在CBC模式中,首先将明文分组与前一个密文分组进行异或运算,然后再进行加密。

异或运算:

异或,英文为exclusive OR,缩写成xor

异或(xor)是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。其运算法则为:

a⊕b = (¬a ∧ b) ∨ (a ∧¬b)

如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0

异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位,所以异或常被认作不进位加法。

异或略称为XOR、EOR、EX-OR

程序中有三种演算子:XOR、xor、⊕。

使用方法如下

z = x ⊕ y

z = x xor y

二.CBC模式加解密过程如下:

1.加密过程例如以下:

  1.  首先将数据依照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
  2.  第一组数据D1与初始化向量iv异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
  3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
  4. 之后的数据以此类推,得到Cn
  5. 按顺序连为C1C2C3......Cn即为加密结果。

2. 解密密过程例如以下:

  1. 首先将数据依照8个字节一组进行分组得到C1C2C3......Cn
  2. 将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)
  3. 将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2
  4. 之后依此类推。得到Dn
  5. 按顺序连为D1D2D3......Dn即为解密结果。

这里注意一点,解密的结果并不一定是我们原来的加密数据,可能还含有你补得位。一定要把补位去掉才是你的原来的数据。

三.CBC模式特点

  • cbc模式在进行加密之前一定会与前一个密文组进行异或运算,因此即使明文D1与明文D2值相等,密文C1与密文C2也不一定是相等的
  • cbc模式无法单独的对一个明文组进行加密,必须有前一个密文组,第一个密文组依赖于IV产生
  • 解密时如果其中一个密文组损坏,只要密文分组的长度没有发生变化,则解密时最多只有2个分组受到数据损坏的影响
  • 资源下载地址 https://download.csdn.net/download/qq_27969037/11327461
  • 5
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
以下是使用SM4算法加密CBC模式的C++代码示例,可以接受输入实现: ```c++ #include <iostream> #include <cstdlib> #include <cstring> #include <openssl/evp.h> #include <openssl/rand.h> #include <openssl/err.h> #define BLOCK_SIZE 16 int main() { // Key and IV setup unsigned char key[BLOCK_SIZE]; unsigned char iv[BLOCK_SIZE]; RAND_bytes(key, BLOCK_SIZE); RAND_bytes(iv, BLOCK_SIZE); // Plaintext and ciphertext buffers unsigned char plaintext[256]; unsigned char ciphertext[256 + BLOCK_SIZE]; memset(plaintext, 0, sizeof(plaintext)); memset(ciphertext, 0, sizeof(ciphertext)); // Get plaintext from user input std::cout << "Enter plaintext: "; std::cin.getline((char*)plaintext, sizeof(plaintext)); // Initialize cipher context EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (!ctx) { std::cerr << "Error initializing cipher context" << std::endl; return EXIT_FAILURE; } // Set cipher type and mode if (EVP_EncryptInit_ex(ctx, EVP_sm4_cbc(), NULL, key, iv) != 1) { std::cerr << "Error setting cipher type and mode" << std::endl; return EXIT_FAILURE; } // Encrypt plaintext int len = 0, ciphertext_len = 0; if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, strlen((const char*)plaintext)) != 1) { std::cerr << "Error encrypting plaintext" << std::endl; return EXIT_FAILURE; } ciphertext_len = len; // Finalize encryption if (EVP_EncryptFinal_ex(ctx, ciphertext + ciphertext_len, &len) != 1) { std::cerr << "Error finalizing encryption" << std::endl; return EXIT_FAILURE; } ciphertext_len += len; // Print ciphertext std::cout << "Ciphertext: "; for (int i = 0; i < ciphertext_len; ++i) { printf("%02x", ciphertext[i]); } std::cout << std::endl; // Clean up EVP_CIPHER_CTX_free(ctx); return EXIT_SUCCESS; } ``` 该示例使用OpenSSL库实现SM4算法加密CBC模式。用户可以通过标准输入方式输入明文,程序会自动输出加密后的密文。注意:SM4算法只支持128位密钥长度,因此key和iv数组的长度均为16。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值