linux下使用openssl 加解密

本文档详细介绍了在Linux系统中如何安装配置OpenSSL,通过genrsa命令生成1024位的私钥,然后利用私钥产生公钥。接着展示了创建并编译rsatest.c代码的过程,用于实现RSA加解密功能。最终,通过`gcc rsatest.c -o hello -lssl`来链接ssl库完成程序的编译。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先附上Linux下安装配置openssl的过程
http://blog.youkuaiyun.com/dazhi_100/article/details/17143213

安装完成后,产生RSA公钥和私钥
输入openssl进入程序
OpenSSL> genrsa -out test.key 1024
产生了1024bit的私钥,然后根据该私钥产生公钥
rsa -in test.key -pubout -out rsatest_pub.key

创建rsatest.c代码如下
vim rsatest.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>



#define OPENSSLKEY "test.key"
#define PUBLICKEY "test_pub.key"
#define BUFFSIZE 1024
char* my_encrypt(char *str,char *path_key);//加密
char* my_decrypt(char *str,char *path_key);//解密
int main(void){
    char *source="i like dancing !";
    char *ptr_en,*ptr_de;
    printf("source is    :%s\n",source);
    ptr_en=my_encrypt(source,PUBLICKEY);
    printf("after encrypt:%s\n",ptr_en);
    ptr_de=my_decrypt(ptr_en,OPENSSLKEY);
    printf("after decrypt:%s\n",ptr_de);
    if(ptr_en!=NULL){
        free(ptr_en);
    }   
    if(ptr_de!=NULL){
        free(ptr_de);
    }   
    return 0;
}
char *my_encrypt(char *str,char *path_key){
    char *p_en;
    RSA *p_rsa;
    FILE *file;
    int flen,rsa_len;
    if((file=fopen(path_key,"r"))==NULL){
        perror("open key file error");
        return NULL;    
    }   
    if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){
        ERR_print_errors_fp(stdout);
        return NULL;
    }   
    flen=strlen(str);
    rsa_len=RSA_size(p_rsa);
    p_en=(unsigned char *)malloc(rsa_len+1);
    memset(p_en,0,rsa_len+1);
    if(RSA_public_encrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_NO_PADDING)<0){
        return NULL;
    }
    RSA_free(p_rsa);
    fclose(file);
    return p_en;
}
char *my_decrypt(char *str,char *path_key){
    char *p_de;
    RSA *p_rsa;
    FILE *file;
    int rsa_len;
    if((file=fopen(path_key,"r"))==NULL){
        perror("open key file error");
        return NULL;
    }
    if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){
        ERR_print_errors_fp(stdout);
        return NULL;
    }
    rsa_len=RSA_size(p_rsa);
    p_de=(unsigned char *)malloc(rsa_len+1);
    memset(p_de,0,rsa_len+1);
    if(RSA_private_decrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_NO_PADDING)<0){
        return NULL;
    }
    RSA_free(p_rsa);
    fclose(file);
    return p_de;
}

检验结果,gcc rsatest.c -o hello -lssl
最后-lssl 是为了引入共享库ssl

Linux下编译rsatest.c

<think>我们正在寻找使用OpenSSL库在Linux环境下进行AES加解密的C语言示例代码。根据引用[1]中提到的,OpenSSL可以通过命令行进行AES加解密,但用户需要的是C语言代码示例。 在OpenSSL库中,AES加解密通常使用EVP(Envelope)接口,这是推荐的方式,因为它提供了更高层次的抽象,支持多种加密算法和模式,并且更注重安全性(如自动处理填充等)。 下面我们将提供一个使用OpenSSL EVP接口进行AES-256-CBC加解密的示例代码。代码将包括以下步骤: 1. 初始化OpenSSL库。 2. 设置加解密上下文(EVP_CIPHER_CTX)。 3. 使用密钥和初始化向量(IV)进行加密或解密操作。 4. 处理数据块,包括最终的填充处理。 5. 清理资源。 注意:在实际应用中,密钥和IV应该通过安全的随机数生成器生成,并且需要妥善保存。这里为了示例,我们使用固定的密钥和IV。 示例代码将分为两个函数:一个用于加密,一个用于解密。 由于用户没有指定具体的模式,我们选择CBC模式(这是常见的模式,并且引用[1]中命令行示例也是CBC模式)。同时,我们使用AES-256,密钥长度为256位(32字节),IV为128位(16字节)。 代码示例:</think>以下是使用 OpenSSL 库在 Linux C 环境中实现 AES-256-CBC 加密解密的完整示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/evp.h> #include <openssl/err.h> #include <openssl/rand.h> #define AES_256_KEY_SIZE 32 // 256-bit key = 32 bytes #define IV_SIZE 16 // 128-bit IV = 16 bytes // 错误处理函数 void handle_errors() { ERR_print_errors_fp(stderr); abort(); } // AES-256-CBC 加密函数 int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext) { EVP_CIPHER_CTX *ctx; int len; int ciphertext_len; // 创建并初始化上下文 if (!(ctx = EVP_CIPHER_CTX_new())) handle_errors(); // 初始化加密操作 if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) handle_errors(); // 执行加密 if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) handle_errors(); ciphertext_len = len; // 完成加密,处理填充 if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handle_errors(); ciphertext_len += len; // 清理上下文 EVP_CIPHER_CTX_free(ctx); return ciphertext_len; } // AES-256-CBC 解密函数 int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext) { EVP_CIPHER_CTX *ctx; int len; int plaintext_len; // 创建并初始化上下文 if (!(ctx = EVP_CIPHER_CTX_new())) handle_errors(); // 初始化解密操作 if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) handle_errors(); // 执行解密 if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) handle_errors(); plaintext_len = len; // 完成解密,移除填充 if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handle_errors(); plaintext_len += len; // 清理上下文 EVP_CIPHER_CTX_free(ctx); return plaintext_len; } int main() { // 初始化 OpenSSLOpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); // 明文数据 unsigned char plaintext[] = "This is a secret message to encrypt!"; printf("Original text: %s\n", plaintext); // 生成随机密钥和 IV (实际应用中应安全存储) unsigned char key[AES_256_KEY_SIZE]; unsigned char iv[IV_SIZE]; if (!RAND_bytes(key, sizeof(key)) || !RAND_bytes(iv, sizeof(iv))) { fprintf(stderr, "Error generating random bytes\n"); exit(EXIT_FAILURE); } // 加密缓冲区 unsigned char ciphertext[128]; int ciphertext_len = aes_encrypt(plaintext, strlen((char *)plaintext), key, iv, ciphertext); printf("Ciphertext length: %d\n", ciphertext_len); // 解密缓冲区 unsigned char decrypted[128]; int decrypted_len = aes_decrypt(ciphertext, ciphertext_len, key, iv, decrypted); decrypted[decrypted_len] = '\0'; // 添加字符串终止符 printf("Decrypted text: %s\n", decrypted); // 清理 OpenSSL 资源 EVP_cleanup(); ERR_free_strings(); return 0; } ``` ### 编译与运行方法 1. 保存为 `aes_example.c` 2. 编译命令: ```bash gcc aes_example.c -o aes_example -lssl -lcrypto ``` 3. 运行程序: ```bash ./aes_example ``` ### 关键组件说明 1. **EVP 接口**:OpenSSL 推荐的高级加密接口,支持多种算法 2. **密钥管理**: - AES-256 需要 32 字节密钥 - 示例中使用 `RAND_bytes()` 生成随机密钥/IV - 实际应用中应通过安全密钥派生函数(如 PBKDF2)生成[^1] 3. **加密模式**: - 使用 CBC 模式(密码分组链接模式) - 需要 16 字节初始化向量(IV) 4. **填充处理**: - 自动使用 PKCS#7 填充 - 解密后自动移除填充 ### 安全注意事项 1. **密钥存储**:实际应用中永远不要硬编码密钥 2. **IV 使用**:每次加密应使用不同 IV(推荐随机生成) 3. **认证**:CBC 模式不提供完整性验证,如需认证应使用 GCM 模式 4. **错误处理**:生产环境需要更完善的错误处理和日志记录 [^1]: 如引用[1]所述,可通过命令行或文件提供密码,但在代码中应使用更安全的密钥派生方式 [^3]: 如引用[3]所建议,OpenSSL 是跨平台加密的可靠选择
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值