我想在openssl / libcrypto中用RSA加密/解密一个长文件(我知道AES更好,但这只是为了比较)。我将输入文件拆分为大小为numBlocks = inputFileLength/maxlen+1
的块maxlen = 200
。我可以在同一个循环中成功编码和解码如下:
for (int i = 0; i < chunks; i++)
{
int bytesDone = i * maxlen;
int remainingLen = inLength - bytesDone;
int thisLen;
if (remainingLen > maxlen)
{
thisLen = maxlen;
} else
{
thisLen = remainingLen;
}
if((encBytes=RSA_public_encrypt(thisLen, data + bytesDone, encryptdata + bytesDone,
rsa_public, RSA_PKCS1_PADDING)) == -1)
{
printf("error\n");
}
if((decBytes=RSA_private_decrypt(encBytes, encryptdata + bytesDone, decryptdata + bytesDone,
rsa_private, RSA_PKCS1_PADDING)) == -1)
{
printf("error\n");
}
}
但是,我想将编码缓冲区encryptdata
保存在二进制文件中,读回二进制文件并解密。我试着这样做:
for (int i = 0; i < chunks; i++)
{
int bytesDone = i * maxlen;
int remainingLen = inLength - bytesDone;
int thisLen;
if (remainingLen > maxlen)
{
thisLen = maxlen;
} else
{
thisLen = remainingLen;
}
if((encBytes=RSA_public_encrypt(thisLen, data + bytesDone, encryptdata + bytesDone,
rsa_public, RSA_PKCS1_PADDING)) == -1)
{
printf("error\n");
}
}
writeFile("encoded.bin",encryptdata,strlen(encryptdata));
size_t size;
unsigned char *readData = readFile("encoded.bin", size);
int inputlen = size;
for (int i = 0; (i * keylen) < inputlen; i++) //keylen = 256
{
int bytesDone = i * keylen;
if((decBytes=RSA_private_decrypt(encBytes, readData + bytesDone, decryptdata + bytesDone,
rsa_private, RSA_PKCS1_PADDING)) == -1)
{
printf("error\n");
}
}
printf("Decrypted text: %s",decryptdata);
readFile
和writeFile
函数如下:
void writeFile(char *filename, unsigned char *file, size_t fileLength
{
FILE *fd = fopen(filename, "wb");
if(fd == NULL) {
fprintf(stderr, "Failed to open file: %s\n", strerror(errno));
exit(1);
}
size_t bytesWritten = fwrite(file, 1, fileLength, fd);
if(bytesWritten != fileLength) {
fprintf(stderr, "Failed to write file\n");
exit(1);
}
fclose(fd);
}
unsigned char* readFile(char *filename, size_t size) {
FILE *fd = fopen(filename, "rb");
if(fd == NULL) {
fprintf(stderr, "Failed to open file: %s\n", strerror(errno));
exit(1);
}
// Determine size of the file
fseek(fd, 0, SEEK_END);
size_t fileLength = ftell(fd);
fseek(fd, 0, SEEK_SET);
size = fileLength;
// Allocate space for the file
unsigned char* buffer = (unsigned char*)malloc(fileLength);
// Read the file into the buffer
size_t bytesRead = fread(buffer, 1, fileLength, fd);
if(bytesRead != fileLength) {
fprintf(stderr, "Error reading file\n");
exit(1);
}
fclose(fd);
return buffer;
}
但是,解密失败并显示错误消息segmentation fault (core dump)
,解密函数仅返回每个块的-1
。任何帮助将不胜感激。
答案 0 :(得分:2)
ReadFile修改参数&#34; size&#34;这是通过值传递的,因此当readfile函数返回时,大小不受影响。
我会按如下方式更改readfile proto:
unsigned char* readFile(char *filename, size_t *size)
然后将调用更改为
unsigned char *readData = readFile("encoded.bin", &size);
最后将readFile大小更新修改为
size = fileLength;
答案 1 :(得分:0)
您的代码中存在各种技术错误,例如在此语句中对二进制数据执行strlen(..)
:
writeFile("encoded.bin",encryptdata,strlen(encryptdata));
encryptdata
是二进制数据,可以包含0
,可以strlen(..)
但主要问题是您尝试使用 RSA 作为分组密码。您加密的块比您加密的块大,但您不能在代码中处理它。您可能能够获得代码来处理此问题,但正确的方法是使用发明用于批量加密的密码,例如 AES 。当您这样做时,您会自动获得对阻止&#39;开箱即用。
除此之外,您还可以获得1000倍的加密速度。