OpenSSL的一些使用案例

发布于:2024-07-03 ⋅ 阅读:(18) ⋅ 点赞:(0)

目录

一、介绍

二、基本使用

1、Shell

(1)文件加解密

(2)生成密钥文件

2、API

(1)md5sum

(2)AES256加解密


一、介绍

        本篇博客重点不是详细描述 OpenSSL 的用法,只是作为日常使用中的一个备忘,方便下次使用时快速索引。后续还会继续补充。

二、基本使用

1、Shell

(1)文件加解密

        需要自定义 key 和 iv

#加密
openssl enc -aes-256-cbc  -K 1234567890 -iv 123456 -in 明文文件 -out 加密文件
#解密
openssl enc -aes-256-cbc -d -K 1234567890 -iv 123456 -in 加密文件 -out 明文文件

(2)生成密钥文件

        生成密钥文件 “ key_chatgpt ”,用户名为 “ user01”,两次输入密码。

[root@iZ2ze3k49h290jqnxmziclZ ssl_key]# echo -n 'user01:' >> key_chatgpt
[root@iZ2ze3k49h290jqnxmziclZ ssl_key]# openssl passwd >> key_chatgpt
Password:
Verifying - Password:
[root@iZ2ze3k49h290jqnxmziclZ ssl_key]# cat key_chatgpt
tpffy:4sx1qNlx9bbTM

        这个密钥文件主要配合 nginx 服务器使用,可以在用户访问网页时输入登录密码。

        nginx 配置文件如下所示。

location /chat.html{
    auth_basic "Restricted site";
    auth_basic_user_file /usr/local/nginx/html/ssl_key/key_chatgpt;
    root html;
}

        界面如下所示,进入 Web 界面后自动弹出。 

2、API

(1)md5sum

        计算文件的 md5 值,用于校验文件是否发生改变。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/md5.h>

//MD5输出的结果为16字节,两个16进制字符表示一个字节,因此结果应为32位
#define MD5_LEN 32 

int cal_md5sum(char *filename, char *md5sum, int res_len)
{
    FILE *file = fopen(filename, "rb");
    if ( !file ) 
    {
        printf("File not found\n");
        return -1;
    }
    
    unsigned char md5_buf[MD5_DIGEST_LENGTH];

    MD5_CTX ctx;
    MD5_Init(&ctx);
    const size_t bufSize = 4096;
    unsigned char *buffer = (unsigned char *)malloc(bufSize);
    int bytesRead = 0;
    
    while ( ( bytesRead = fread(buffer, 1, bufSize, file) ) ) 
    {
        MD5_Update(&ctx, buffer, bytesRead);
    }
    
    free(buffer);
    fclose(file);
    
    MD5_Final(md5_buf, &ctx);
    
    char hex[MD5_LEN+1] = {0};
    memset(md5sum, 0, res_len);
    if ( res_len >= MD5_LEN + 1 )
    {
        for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) 
        {
            sprintf(md5sum + 2 * i, "%02x", md5_buf[i]);
        }
    }
    else
    {
        printf("res len is invalid\n");
        return -1;
    }
}

int main(int argc, char *argv[]) 
{
    
    char *md5sum = (char *)malloc(sizeof(char) * (MD5_LEN + 1));

    if ( cal_md5sum(argv[1], md5sum, MD5_LEN + 1) < 0 )
    {
        printf("calculate failed\n");
        exit(-1);
    }

    printf("%s  %s\n", md5sum, argv[1]);

    free(md5sum);

    return 0;
}

        运行截图如下所示。 

(2)AES256加解密

        可用于对 socket 通讯过程中的数据进行加解密。通讯两端需要自行协商 key 和 iv。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <openssl/aes.h>

#define AESKEY "df98b715d5c6ed2b25817b6f255411a1"	//HEX密钥
#define AESIV "2841ae97419c2973296a0d4bdfe19a4f"	//HEX初始向量

unsigned char* str2hex(char *str)	
 {
    unsigned char *ret = NULL;
    int str_len = strlen(str);
    int i = 0;
    assert((str_len % 2) == 0);
    ret = (char *)malloc(str_len / 2);
    for (i = 0;i < str_len; i = i + 2 ) 
    {
        sscanf(str+i, "%2hhx", &ret[i / 2]);
    }
    return ret;
}

int main()
{
    AES_KEY encryptkey;
    AES_KEY decryptkey;

    unsigned char *key;
    unsigned char *stdiv;

    key = str2hex(AESKEY);
    stdiv = str2hex(AESIV);

    AES_set_encrypt_key(key, 256, &encryptkey);
    AES_set_decrypt_key(key, 256, &decryptkey);

    unsigned char plain_text [32];

    memcpy(plain_text, "AES encrypt in openssl demo", 27);
    memset(plain_text + 27, 0, 5);
    printf("plain_text: ");

    for(int i = 0; i < 32; i++)
    {
        printf("%02X ", plain_text[i]);
    }
    printf("\n");
    printf("plain_text : %s\n", plain_text);

    unsigned char encrypted_text [32];

    memset(encrypted_text, 0, 32);
    unsigned char tmpiv[16];
    memcpy(tmpiv, stdiv, 16);
    AES_cbc_encrypt(plain_text, encrypted_text, 32, &encryptkey, tmpiv, AES_ENCRYPT);

    printf("encrypted_text: ");
    for(int i = 0; i < 32; i++)
    {
        printf("%02X ", encrypted_text[i]);
    }
    printf("\n");


    unsigned char decrypted_text [32];

    memset(decrypted_text, 0, 32);
    memcpy(tmpiv, stdiv, 16);
    AES_cbc_encrypt(encrypted_text, decrypted_text, 32, &decryptkey, tmpiv, AES_DECRYPT);

    printf("decrypted_text: ");
    for(int i = 0; i < 32; i++)
    {
        printf("%02X ", decrypted_text[i]);
    }
    printf("\n");
    printf("decrypted_text: %s\n", decrypted_text);

    return 0;
}

        运行截图如下所示。

--------------------------------------- 废话分界线 ----------------------------------------------

--------------------------------------- 废话分界线 ----------------------------------------------

--------------------------------------- 废话分界线 ----------------------------------------------

OpenSSL是一种开放源代码的软件库包,它为应用程序提供安全通信功能,以避免窃听并确认通信双方的身份

OpenSSL的全称是Open Secure Sockets Layer,广泛被应用在互联网的网页服务器上。它是在上世纪90年代中期由Eric A. Young和Tim J. Hudson编写的,旨在提供一个没有太多限制的开放源代码的安全套接层协议实现。作为一个强大的密码库,OpenSSL不仅在网络传输层上保护数据安全,还提供了丰富的加密、解密、证书管理等功能。下面将具体介绍OpenSSL:

  1. 主要组成:OpenSSL包含三个主要的功能部分:SSL协议库、应用程序以及密码算法库。其中,SSL(Secure Sockets Layer)协议是互联网上保密通讯的工业标准,由Netscape公司提出,目标是保证两个应用间通信的保密性和可靠性。
  2. 加密算法:OpenSSL支持多种对称加密和非对称加密算法。对称加密算法包括AES、DES、Blowfish等,而非对称加密算法则有DH算法、RSA算法、DSA算法和椭圆曲线算法等。这些加密算法确保数据在传输过程中的安全性和完整性。
  3. 密钥管理:OpenSSL提供了密钥和证书管理功能,支持ASN.1的证书和密钥相关标准,包括对证书、公钥、私钥、证书请求以及CRL等数据对象的DER、PEM和BASE64编解码功能。它还实现了私钥的PKCS#12和PKCS#8的编解码功能,并提供了对私钥的加密保护。
  4. 协议实现:OpenSSL实现了SSL协议的多个版本,包括SSLv2、SSLv3以及TLSv1.0。这些协议的版本在细节上略有不同,但总体目标是通过加密和认证机制保障互联网通信的安全。
  5. 应用场景:OpenSSL广泛应用于各种网络安全协议中,例如HTTPS就是将HTTP协议通过SSL加密实现安全的网页浏览。除此之外,VPN、加密的电子邮件协议等也常用到OpenSSL。

总结来说,OpenSSL不仅是一个功能强大的密码学库,还是一个多用途的、跨平台的安全工具。其开源特性和广泛的适用性使其成为技术人员在进行安全开发时的重要选择。