用EVP_CipherUpdate加密和解密,写个例子
时间: 2023-12-22 21:04:53 浏览: 129
好的,以下是一个使用 OpenSSL EVP 接口进行加密和解密的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#define BUF_SIZE 1024
int main(int argc, char *argv[]) {
EVP_CIPHER_CTX *ctx;
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
unsigned char in_buf[BUF_SIZE], out_buf[BUF_SIZE + EVP_MAX_BLOCK_LENGTH];
int in_len, out_len, total_len = 0, final_len;
const EVP_CIPHER *cipher;
int i;
// 初始化 OpenSSL 库
OpenSSL_add_all_algorithms();
// 获取加密算法
cipher = EVP_get_cipherbyname("aes-256-cbc");
if (!cipher) {
fprintf(stderr, "Error: no such cipher\n");
exit(1);
}
// 生成随机密钥和 IV
if (EVP_BytesToKey(cipher, EVP_sha256(), NULL, (unsigned char *) argv[1], strlen(argv[1]), 1, key, iv) != EVP_CIPHER_key_length(cipher)) {
fprintf(stderr, "Error: unable to generate key and iv\n");
exit(1);
}
// 创建加密上下文
ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
fprintf(stderr, "Error: unable to create cipher context\n");
exit(1);
}
// 初始化加密上下文
if (EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv) != 1) {
fprintf(stderr, "Error: unable to initialize cipher context\n");
exit(1);
}
// 读取输入数据并逐块加密
while ((in_len = fread(in_buf, 1, BUF_SIZE, stdin)) > 0) {
if (EVP_EncryptUpdate(ctx, out_buf, &out_len, in_buf, in_len) != 1) {
fprintf(stderr, "Error: unable to encrypt data\n");
exit(1);
}
fwrite(out_buf, 1, out_len, stdout);
total_len += out_len;
}
// 完成加密
if (EVP_EncryptFinal_ex(ctx, out_buf, &final_len) != 1) {
fprintf(stderr, "Error: unable to finalize cipher context\n");
exit(1);
}
fwrite(out_buf, 1, final_len, stdout);
total_len += final_len;
// 输出加密后的数据长度
fprintf(stderr, "Encrypted %d bytes of data\n", total_len);
// 重置加密上下文
if (EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv) != 1) {
fprintf(stderr, "Error: unable to reset cipher context\n");
exit(1);
}
// 读取加密后的数据并逐块解密
total_len = 0;
while ((in_len = fread(in_buf, 1, BUF_SIZE, stdin)) > 0) {
if (EVP_DecryptUpdate(ctx, out_buf, &out_len, in_buf, in_len) != 1) {
fprintf(stderr, "Error: unable to decrypt data\n");
exit(1);
}
fwrite(out_buf, 1, out_len, stdout);
total_len += out_len;
}
// 完成解密
if (EVP_DecryptFinal_ex(ctx, out_buf, &final_len) != 1) {
fprintf(stderr, "Error: unable to finalize cipher context\n");
exit(1);
}
fwrite(out_buf, 1, final_len, stdout);
total_len += final_len;
// 输出解密后的数据长度
fprintf(stderr, "Decrypted %d bytes of data\n", total_len);
// 清理加密上下文
EVP_CIPHER_CTX_free(ctx);
// 清理 OpenSSL 库
EVP_cleanup();
return 0;
}
```
该程序使用 AES-256-CBC 加密算法对标准输入中的数据进行加密,并将加密后的数据输出到标准输出。然后,它使用相同的密钥和 IV 对加密后的数据进行解密,并将解密后的数据输出到标准输出。
为了编译这个程序,你需要安装 OpenSSL 库,并使用以下命令进行编译:
```
gcc -o example example.c -lssl -lcrypto
```
然后,你可以使用以下命令运行程序:
```
./example mypassword < input.txt > output.txt
```
其中,`mypassword` 是用于生成密钥和 IV 的密码,`input.txt` 是要加密的文件,`output.txt` 是加密后的文件。
阅读全文