• 通过openssl非对称加密解密


    最近有项目需要实现加密和解密,实际使用通过openssl的对称加密去实现。在看了对称加密后,顺便也看了一下非对称加密(以RSA为例),在此做一下记录,便于今后要用的时候可以回头来看看。

    一、命令行的方式

    1. 生成秘钥

    openssl genrsa -out private.pem 秘钥长度默认为1024

    2. 根据私钥导出公钥

    openssl rsa -in private.pem -pubout -out public.pem

    3. 通过公钥对文件进行加密

    openssl rsautl -encrypt -pubin -inkey public.pem -in plainFile -out encryptedFile

    注意,这里使用公钥的话,需要写成 -pubin -inkey,单独-inkey表示私钥。因此通过私钥加密的话,命令行如下所示:

    openssl rsautl -encrypt -inkey private.pem -in plainFile -out encryptedFile

    4. 通过私钥进行解密

    openssl rsautl -decrypt -inkey private.pem -in encryptedFile -out plainFile

    解密我试了一下,只能通过私钥来进行。

    但是如果直接使用秘钥来加密、解密的话,对内容长度有限制。比如秘钥长度为1024时,加密的时候,最多只能加密124个字节,所以文件长度超过124个字节时,就会报错。如果要加密、解密大文件,可以通过证书和smime应用来进行。

    5. 大文件的加密和解密

    生成私钥和证书:

    sudo openssl req -x509 -nodes -days 100000 -newkey rsa:2048 -keyout private.pem -out cacert.pem

    生成私钥和证书的时候,会要求输入信息,国家、省份等信息。

    注:证书是用来确保被访问的对象是可信的。但是证书本身如何证明是可靠的呢?证书由机构发布(CA),证书上带有机构的签名。通讯过程中,客户端与服务器建立连接后,服务器将证书发给客户端。客户端利用CA的公钥对证书签名进行验证。因此从证书可以到处公钥,通过openssl x509 -in cacert.pem -pubkey -noout -out demo.pem。这里demo.pem就是公钥。同样的,也可以使用rsa指令根据私钥去到处公钥,经过对比,两种方式导出的公钥是一模一样的。

    通过证书对文件进行加密:

    openssl smime -encrypt -in plainFile -out encryptedFile cacert.pem

    通过私钥对文件进行解密:

    openssl smime -decrypt -in encryptedFile -out plainFile -inkey private.pem

    二、调用EVP函数实现

    1.加密

    加密主要通过EVP_Seal**函数去实现。包括EVP_SealInit,EVP_SealUpdate和EVP_SealFinal。

    2.解密

    解密主要通过EVP_Open**函数去实现。包括EVP_OpenInit,EVP_OpenUpdate和EVP_OpenFinal。

    3. demo

    int test_EVP_Enveloped(void)
    {
        int ret = 0;
        EVP_CIPHER_CTX *ctx = NULL;
        EVP_PKEY *keypair = NULL;
        unsigned char *kek = NULL;
        unsigned char iv[EVP_MAX_IV_LENGTH];
        static const unsigned char msg[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
        int len, kek_len, ciphertext_len, plaintext_len;
        unsigned char ciphertext[32], plaintext[16];
        const EVP_CIPHER *type = EVP_aes_256_cbc();

        if (!TEST_ptr(keypair = load_example_rsa_key())
                || !TEST_ptr(kek = OPENSSL_zalloc(EVP_PKEY_size(keypair)))
                || !TEST_ptr(ctx = EVP_CIPHER_CTX_new())
                || !TEST_true(EVP_SealInit(ctx, type, &kek, &kek_len, iv,
                                           &keypair, 1))
                || !TEST_true(EVP_SealUpdate(ctx, ciphertext, &ciphertext_len,
                                             msg, sizeof(msg)))
                || !TEST_true(EVP_SealFinal(ctx, ciphertext + ciphertext_len,
                                            &len)))
            goto err;

        ciphertext_len += len;

        if (!TEST_true(EVP_OpenInit(ctx, type, kek, kek_len, iv, keypair))
                || !TEST_true(EVP_OpenUpdate(ctx, plaintext, &plaintext_len,
                                             ciphertext, ciphertext_len))
                || !TEST_true(EVP_OpenFinal(ctx, plaintext + plaintext_len, &len)))
            goto err;

        plaintext_len += len;
        if (!TEST_mem_eq(msg, sizeof(msg), plaintext, plaintext_len))
            goto err;

        ret = 1;
    err:
        OPENSSL_free(kek);
        EVP_PKEY_free(keypair);
        EVP_CIPHER_CTX_free(ctx);
        return ret;
    }

  • 相关阅读:
    如何一次性批量打印PDF、Word、Excel、PPT和图片 - 文件批量打印工具
    Linux基础——定时任务
    Game101作业5以及光线追踪笔记
    go error处理
    物联网开发笔记(7)- 使用Wokwi仿真ESP32开发板实现LED灯点亮、按钮使用
    Generative AI 新世界 | Falcon 40B 开源大模型的部署方式分析
    神经网络在控制中的作用,间歇控制器的工作原理
    MySQL--创建,删除,查找,案例
    .NET/JAVA/GO 固定时间窗口算法实现(无锁线程安全)
    《微服务架构设计模式》第二章
  • 原文地址:https://blog.csdn.net/guolisong/article/details/127998337