gpt4 book ai didi

c - 使用 EVP 和 OpenSSL,用 C 编码

转载 作者:太空宇宙 更新时间:2023-11-04 03:39:25 24 4
gpt4 key购买 nike

我看到很多关于 OpenSSL 和 EVP 的问题,但没有很多明确的答案,但我想我仍然会在这里发布我的问题并希望得到更好的反馈。

给我的 Material 是一个签名文件“symmetrickey.bin”,一个RSA key 集“privatekey_A.pem”,“publickey_A.pem”,以及其他用户的公钥“publickey_B.pem”。

我需要做的是:

  1. 取消签署 symmetrickey.bin 并将其存储到文本文件中。
  2. 使用 symmetrickey.txt 和一些算法(例如 AES)加密 message.txt
  3. 使用 privatekey_A.pem 对加密消息进行签名并写入文件 cipher.bin
  4. 之后,我需要取消签名并验证 cipher.bin 上的签名。
  5. 然后用我们的对称 key 解密消息,然后写入另一个文件。

我遇到的问题是了解如何实现 OpenSSL EVP 库。 API页面不是很清楚每个函数的值来自哪里。例如,EVP_OpenInit() 我从哪里得到 ekek“ekl”的长度? “prvi”是私钥吗?我怎么知道类型?这些是我没有得到的东西。

我看过很多实现,但大多数都没有回答我的问题,或者它们提供了疯狂的代码,几乎没有解释正在发生的事情或值的来源。我在这里发帖作为最后的手段......

最佳答案

对于签名/取消签名 key 部分,我需要更多信息,这个签名是如何完成的?例如,这个签名是否在文件末尾有 X 字节长度,然后可以轻松删除?

对于列表中的第 2-5 项,以下代码肯定会有所帮助,它基于 openssl 文档中的示例,并根据您的需要进行了更多评论和改编。如果您有任何未评论的问题,请随时提出!

crpytor.c

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <openssl/evp.h>

#define APPNAME "C"

#define CHUNK_SIZE 512
int do_crypt(FILE *in, FILE *out, int do_encrypt)
{
/* Allow enough space in output buffer for additional block */
unsigned char inbuf[CHUNK_SIZE];
unsigned char outbuf[CHUNK_SIZE + EVP_MAX_BLOCK_LENGTH];
int inlen;
int outlen;
EVP_CIPHER_CTX ctx;
/* Bogus key and IV: we'd normally set these from
* another source.
*/
unsigned char key[] = { 0x13, 0xa3, 0xb4, 0xc1, 0x24, 0x19, 0xf5, 0x23, 0x18, 0xef, 0xca, 0x12, 0x4c, 0x9f, 0x14, 0xfe };
unsigned char iv[] = { 0x92, 0x1c, 0x23, 0x3f, 0x5e, 0x10, 0x3d, 0x9a };
/* Don't set key or IV because we will modify the parameters */
EVP_CIPHER_CTX_init(&ctx);
/* Using Blowfish encryption with cbc algorithm, you can use whichever is supported in openssl if you wish */
EVP_CipherInit_ex(&ctx, EVP_bf_cbc(), NULL, NULL, NULL, do_encrypt);
EVP_CIPHER_CTX_set_key_length(&ctx, 16);
/* We finished modifying parameters so now we can set key and IV */
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
for(;;)
{
inlen = fread(inbuf, 1, CHUNK_SIZE, in);
if(inlen <= 0) break;
if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
{
/* Error */
EVP_CIPHER_CTX_cleanup(&ctx);
return -1;
}
fwrite(outbuf, 1, outlen, out);
}
if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
{
/* Error */
EVP_CIPHER_CTX_cleanup(&ctx);
return -1;
}
fwrite(outbuf, 1, outlen, out);
EVP_CIPHER_CTX_cleanup(&ctx);
rewind(in);
rewind(out);
return 0;
}

/* This is the standalone encryptor entry point */
int main(int argc, char** argv)
{
FILE *encode_file;
FILE *decode_file;
int enc_or_dec;
if (argc < 4)
{
printf("Usage: %s [plain file] [encrypted file] [0/1 deccrypt/encrypt]\n", argv[0]);
return -1;
}
encode_file = fopen(argv[1], "r");
decode_file = fopen(argv[2], "w+");
/* Stupid decimal translation */
enc_or_dec = *argv[3]-48;

do_crypt(encode_file, decode_file, enc_or_dec);
return 0;
}

和 Makefile:

all:
gcc cryptor.c -o cryptor -g -lcrypto -I ../openssl-1.0.1f-host/include
clean:
rm cryptor

此代码不使用 EVP_OpenInit(),因为它仅用于解密,而我的方法(和您的需求)需要加密或解密。虽然您可以使用 EVP_OpenInit() 初始化解密上下文,但我将仅适用于解密的单个调用替换为适用于加密和解密的两个调用。

来自手册页:

EVP_OpenInit() initializes a cipher context ctx for decryption with cipher type. It decrypts the encrypted symmetric key of length ekl bytes passed in the ek parameter using the private key priv. The IV is supplied in the iv parameter. EVP_OpenUpdate() and EVP_OpenFinal() have exactly the same properties as the EVP_DecryptUpdate() and EVP_DecryptFinal() routines, as documented on the EVP_EncryptInit(3) manual page.

EVP_OpenInit() 关键文件

如果您引用的签名文件是 RSA/DSA 或类似格式的公钥文件,您可以使用 this StackOverflow question比我更好的方法,因为它会自动从文件中提取 key (并根据需要使用 EVP_OpenInit())

关于c - 使用 EVP 和 OpenSSL,用 C 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29874150/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com