C++实现CTR加密模式

CTR模式克服了CBC需要串行加密的劣势。它不需要依赖块之间的链接,可以并行处理加密操作,不需要填充,适合处理任意长度的数据。

CTR模式的加密步骤:
1.先定义一个初始向量(IV)和计数器(Counter)。
2.对每个块的计数器值进行加密生成伪随机密钥流。
3.将密钥流和明文按位异或运算,生成密文。
4.计数器逐步增加,直到加密完成。

CTR不需要依赖前一个密文块,可以同时处理不同的块,因此它在并行化处理时性能更好。

解密过程
与加密过程相同,使用相同的IV和密钥生成伪随机数流。
将伪随机数流与密文进行异或操作,生成原始的明文块。

C++代码实现如下:

#include <openssl/evp.h>
#include <openssl/rand.h>
#include <cstring>
#include <iostream>

const int AES_KEY_LENGTH = 256;
const int AES_BLOCK_SIZE = 16;

void handleErrors() {
    std::cerr << "发生错误\n";
    exit(1);
}

// AES CTR模式加密
int encrypt_ctr(unsigned char *plaintext, int plaintext_len, unsigned char *key,
                unsigned char *iv, unsigned char *ciphertext) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();// *ciphertext直接对密文数据进行更改 
    if (!ctx) handleErrors();//失败给出错误提示 

    if (EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv) != 1)
        handleErrors();//初始化加密操作 

    int len;
    int ciphertext_len;

    if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len) != 1)
        handleErrors();//执行加密操作 
    ciphertext_len = len;

    if (EVP_EncryptFinal_ex(ctx, ciphertext + len, &len) != 1)
        handleErrors();//完成加密 
    ciphertext_len += len;

    EVP_CIPHER_CTX_free(ctx);
    return ciphertext_len;
}

// AES CTR模式解密
int decrypt_ctr(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
                unsigned char *iv, unsigned char *plaintext) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    if (!ctx) handleErrors();

    if (EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv) != 1)
        handleErrors();//初始化解密过程 

    int len;
    int plaintext_len;

    if (EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len) != 1)
        handleErrors();//执行解密 操作 
    plaintext_len = len;

    if (EVP_DecryptFinal_ex(ctx, plaintext + len, &len) != 1)
        handleErrors();
    plaintext_len += len;//完成解密 

    EVP_CIPHER_CTX_free(ctx);
    return plaintext_len;
}

int main() {
    unsigned char key[AES_KEY_LENGTH / 8];//定义密钥长度 
    unsigned char iv[AES_BLOCK_SIZE];//初始化向量,通过ssl中的rand生成 

    if (!RAND_bytes(key, sizeof(key)) || !RAND_bytes(iv, sizeof(iv))) {
        std::cerr << "Error generating key/iv\n";
        return 1;
    }//随机生成密钥与初始化向量 
    unsigned char plaintext[] = "Hello,world!";
    unsigned char ciphertext[128];//密文 
    unsigned char decryptedtext[128];//解密后的结果 
    std::cout << "\n明文:\n" << plaintext << std::endl;  
    

    int ciphertext_len = encrypt_ctr(plaintext, strlen((char *)plaintext), key, iv, ciphertext);
	//计算加密后的密文长度 
    int decryptedtext_len = decrypt_ctr(ciphertext, ciphertext_len, key, iv, decryptedtext);
    decryptedtext[decryptedtext_len] = '\0';
    //计算解密后的明文长度 

    std::cout << "对明文加密后的密文:\n";
    for (int i = 0; i < ciphertext_len; i++) {
        std::cout << std::hex << (int)ciphertext[i];
    }
    std::cout << "\n解密后的明文:\n" << decryptedtext << std::endl;

    return 0;
}

执行结果如图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺旺的碎冰冰~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值