首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenSSL加密/解密

OpenSSL加密/解密
EN

Stack Overflow用户
提问于 2013-01-03 19:15:18
回答 3查看 1.7K关注 0票数 1

我目前正在尝试编写一个简单的程序,它可以加密二进制文件(.zip),以另一种格式( .cry )保存它,然后将.cry文件解密回其原始状态。

我没有收到任何错误,但是当我试图打开解密的.zip文件时,我从存档程序中得到了一个错误。

注意:原始的.zip文件只包含一个写有3个单词的小.txt文件。

代码语言:javascript
复制
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/rand.h>


int main(){
const EVP_CIPHER* pCipher = EVP_aes_128_ecb();
EVP_CIPHER_CTX* pCtx = new EVP_CIPHER_CTX;
//int nBl = EVP_CIPHER_CTX_block_size( pCtx );
FILE *fin;
FILE *fout;
FILE *fdecr;
long fin_size,fout_size,fdecr_size;
unsigned char *fin_buf;
unsigned char *fout_buf;
unsigned char *fdecr_buf;

size_t rezultat;


fin = fopen("arhiva.zip", "rb");
fout = fopen("arhiva.zip.cry","wb");
fdecr= fopen("decript.zip","wb");
if (fin==NULL)
    {fputs ("File error",stderr); exit (1);}
if (fout==NULL)
    {fputs ("File error",stderr); exit (1);}
if (fdecr==NULL)
    {fputs ("File error",stderr); exit (1);}


fseek (fin , 0 , SEEK_END);
fin_size = ftell (fin);
fout_size=fin_size;
fdecr_size=fin_size;
rewind (fin);
fin_buf = (unsigned char*) malloc (sizeof(unsigned char)*fin_size);

fdecr_buf= (unsigned char*) malloc (sizeof(unsigned char)*fin_size);
if (fin_buf == NULL) {fputs ("Memory error",stderr); exit (2);}
//if (fout_buf == NULL) {fputs ("Memory error",stderr); exit (2);}
if (fdecr_buf == NULL) {fputs ("Memory error",stderr); exit (2);}

//copiere fisier in buffer
rezultat = fread (fin_buf,1,fin_size,fin);
if (rezultat != fin_size) {fputs ("Reading error",stderr); exit (3);}



      //pregatire criptare
OpenSSL_add_all_ciphers();

EVP_CIPHER_CTX_init( pCtx );

unsigned char pKey[192];
unsigned char pIV[192];
RAND_bytes(pKey,24);
RAND_bytes(pIV,24);

EVP_EncryptInit_ex( pCtx, pCipher, NULL, pKey, pIV);
EVP_DecryptInit_ex( pCtx, pCipher, NULL, pKey, pIV);

      //cript

int nOutLen = 0;
int nTmpOutLen = 0;

fout_buf = (unsigned char*) malloc (sizeof(unsigned char)*fout_size);
memset( fout_buf, 0, fout_size);

EVP_EncryptUpdate( pCtx,fout_buf,&nTmpOutLen,fin_buf,fin_size );
nOutLen += nTmpOutLen;
EVP_EncryptFinal( pCtx,fout_buf + nTmpOutLen,&nTmpOutLen );
fwrite(fout_buf, 1, fout_size, fout);

//decript
nOutLen = 0;
nTmpOutLen = 0;
memset( fdecr_buf, 0, fdecr_size);

EVP_DecryptUpdate(pCtx,fdecr_buf,&nTmpOutLen,fout_buf,fout_size );
nOutLen += nTmpOutLen;
EVP_DecryptFinal( pCtx,fdecr_buf + nTmpOutLen,&nTmpOutLen );
fwrite(fdecr_buf, 1, fdecr_size, fdecr);


fclose(fin);
fclose(fout);
fclose(fdecr);
EVP_CIPHER_CTX_cleanup(pCtx);


return 0;

}

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-03 22:26:20

对于更新部分,nOutLennTmpOutLen增加,但对于完成部分则不增加。

票数 1
EN

Stack Overflow用户

发布于 2013-01-03 20:44:22

看起来您没有将整个加密/解密输出写入到文件中。在那里写nOutLen,而不是fdecr_size。您使用的是ECB模式,因此您的加密数据将填充到16字节边界。另外,我建议使用CBC模式。

票数 3
EN

Stack Overflow用户

发布于 2013-01-03 23:29:59

这里有很多问题:

  • 代码假定加密文件与原始文件的大小相同。通常情况并非如此,尤其是对于您正在使用的ECB模式中的AES-128这样的块密码。实际上,在对EVP_EncryptFinal().
  • You的调用中,您会使fout_buf溢出,因此需要正确地计算nOutLen操作(包括*Final),并处理这么多字节的加密或解密输出。例如,您只将fout_size字节的加密数据写入.cry文件,这比OpenSSL写入缓冲区的字节要少,这反过来会导致解密后损坏的最后一个块,从而导致归档程序错误。
  • 您使用相同的上下文pCtx交错进行加密和解密。对于加密和decryption.
  • You,您应该使用单独的上下文结构为pKeypIV保留192个字节,然后分别用随机数据填充24个字节,但最终只有16个字节的密钥被OpenSSL使用(AES-128),并且没有IV (ECB模式不使用IV)。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14137822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档