对于签名/取消签名密钥部分,我需要更多信息,这个签名是如何完成的?例如,这个签名是否是文件末尾的 X 字节长度,然后可以轻松删除?
对于列表中的第 2-5 项,以下代码肯定会有所帮助,它基于 openssl 文档中的示例,并根据您的需要进行了更多注释和修改。如果您有任何未评论的问题,请随时询问!
密码器.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()
使用密码类型初始化ctx
用于解密的密码上下文。它使用私钥对参数中ekl
传递的长度字节的加密对称密钥进行解密。IV 在参数中提供。并具有与和
例程
完全相同的属性,如
手册页中所述。ek
priv
iv
EVP_OpenUpdate()
EVP_OpenFinal()
EVP_DecryptUpdate()
EVP_DecryptFinal()
EVP_EncryptInit(3)
EVP_OpenInit()
对于关键文件
如果您所指的签名文件是 RSA/DSA 或类似格式的公钥文件,您可以使用这个 StackOverflow 问题获得比我更好的方法,因为它会自动从文件中提取密钥(并按照EVP_OpenInit()
您的要求使用)