Для части ключа подписи/отмены подписи мне нужна дополнительная информация, как делается эта подпись? Например, является ли эта подпись длиной 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()
инициализирует контекст шифрования ctx
для расшифровки с типом шифрования. Он расшифровывает зашифрованный симметричный ключ длиной ekl
байт, переданный в параметре ek
, используя закрытый ключ priv
. IV предоставляется в параметре iv
. EVP_OpenUpdate()
и EVP_OpenFinal()
имеют те же свойства, что и подпрограммы EVP_DecryptUpdate()
и EVP_DecryptFinal()
, как описано на странице руководства EVP_EncryptInit(3)
.
EVP_OpenInit()
для ключевых файлов
Если подписанный файл, на который вы ссылаетесь, является файлом открытого ключа в RSA/DSA или аналогичном формате, вы можете использовать этот вопрос StackOverflow для лучшего метода, чем мой, поскольку он автоматически извлекает ключ из файла (и использует EVP_OpenInit()
, как вам нужно )
person
Ishay Peled
schedule
26.04.2015