用C实现OpenSSL的DES解密

vhmi4jdf  于 2023-04-05  发布在  其他
关注(0)|答案(1)|浏览(202)

我想写一个程序来加密和传输文件。这是我的程序的一部分:

char buf[BUF_SIZE],decrypted[BUF_SIZE+EVP_MAX_BLOCK_LENGTH];
   int cipher_size,decrypted_size;
    while(1)
    {
        read(clnt_sock,(char*)&cipher_size,sizeof(cipher_size));
        read(clnt_sock,buf,cipher_size);
        des_decrypt((unsigned char *)buf,cipher_size,(unsigned char*)argv[2],
                (unsigned char*)decrypted,&decrypted_size);
        fwrite(buf,1,decrypted_size,fp);
    }
void des_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *plaintext, int *plaintext_len) {
    EVP_CIPHER_CTX *ctx;
    int len;
    if(!(ctx = EVP_CIPHER_CTX_new())) {
        return;
    }
    if(1 != EVP_DecryptInit_ex(ctx, EVP_des_ecb(), NULL, key, NULL)) {
        err("DES init error!");
        return;
    }
    if(1 != EVP_DecryptUpdate(ctx, plaintext, plaintext_len, ciphertext, ciphertext_len)) {
        err("Decrypt error!");
        return;
    }
    if(1 != EVP_DecryptFinal_ex(ctx, plaintext + *plaintext_len, &len)) {
        err("Final Decrypt error");
        return;
    }
    *plaintext_len += len;
    EVP_CIPHER_CTX_free(ctx);
}

但是des_decrypt函数总是在第二个return语句返回值plaintext_len为零。我试着调试,发现EVP_DecrypInit_ex的返回值总是1。
我只是想知道是什么原因导致了这个问题,以及如何解决它,谢谢!!
在Ubuntu 22.x上。

1yjd4xko

1yjd4xko1#

如果您的OpenSSL版本大于3.0。您需要加载遗留提供程序。在此URL中:https://www.openssl.org/docs/man3.0/man7/EVP_CIPHER-DES.html
旧提供程序中提供了以下算法:

"DES-ECB"
 "DES-CBC"
 "DES-OFB"
 "DES-CFB", "DES-CFB1" and "DES-CFB8"
 "DESX-CBC"

您需要加载旧版提供程序。

#include <openssl/provider.h>

OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy");
if (legacy == NULL)
{
    printf("Failed to load Legacy provider\n");
}

最终代码:

#include "bits/stdc++.h"
#include <openssl/evp.h>
#include <openssl/provider.h>
using namespace std;

void des_decrypt(unsigned char *ciphertext, int ciphertext_len, 
unsigned char *key, unsigned char *plaintext, int *plaintext_len)
{
    OPENSSL_init();
    EVP_CIPHER_CTX *ctx;
    int len;
    if (!(ctx = EVP_CIPHER_CTX_new()))
    {
        return;
    }
    EVP_CIPHER_CTX_init(ctx);
    if (1 != EVP_DecryptInit_ex(ctx, EVP_des_ecb(), NULL, key, NULL))
    {
        printf("DES init error!");
        return;
    }
    if (1 != EVP_DecryptUpdate(ctx, plaintext, plaintext_len, ciphertext, ciphertext_len))
    {
        printf("Decrypt error!");
        return;
    }
    if (1 != EVP_DecryptFinal_ex(ctx, plaintext + *plaintext_len, &len))
    {
        printf("Final Decrypt error");
        return;
    }
    *plaintext_len += len;
    EVP_CIPHER_CTX_free(ctx);
}

int main(int argc, char *argv[])
{
    OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy");
    if (legacy == NULL)
    {
        printf("Failed to load Legacy provider\n");
    }

    uint8_t key[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38};
    uint8_t ct[] = {0x96, 0xd0, 0x02, 0x88, 0x78, 0xd5, 0x8c, 0x89, 0xfe, 0xb9, 0x59, 0xb7, 0xd4, 0x64, 0x2f, 0xcb};

    uint8_t plain[32] = {0};
    int plain_len = 32;
    des_decrypt(ct, 16, key, plain, &plain_len);
    printf("%s\n", plain);
    return 0;
}

输出:12345678

相关问题