首先,可能需要熟悉您的流密码。Blowfish 使用 64位块大小进行加密/解密;不是字节。只要您了解您所指的 64“字节”是您的要求而不是 Blowfishes,并且 Blowfish 只需要 8 字节块。
也就是说,循环传递一个大小是算法块大小的倍数的文件,一次提取一个 64 字节帧的解密数据当然是可行的。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <openssl/blowfish.h>
int main(int argc, char *argv[])
{
if (argc < 2)
return EXIT_FAILURE;
FILE * fp = fopen(argv[1], "rb");
if (fp == NULL)
{
perror(argv[1]);
return EXIT_FAILURE;
}
// your key bytes would be here (obviously).
unsigned char key[16] = "1234567890123456";
int key_len = sizeof(key)-1;
// setup the key schedule.
BF_KEY bf_key;
BF_set_key(&bf_key, key_len, key);
// and setup the initialization vector. normally the IV is
// randomly generated when encrypting, then stored as the
// lead 8 bytes of ciphertext output. this assumes you're
// iv is static (all zeros) similar to SSH
unsigned char iv[8] = {0};
int n = 0;
// finally, begin reading the data in chunks of 64 bytes
// sending it through the blowfish algorithm
unsigned char source[64];
unsigned char dest[64];
while (fread(source, sizeof(source), 1, fp) == 1)
{
BF_cfb64_encrypt(source, dest, sizeof(dest), &bf_key, iv, &n, BF_DECRYPT);
// do something with your dest[] plaintext block
}
fclose(fp);
return 0;
}
该示例相当微不足道,但它提出了一些您可能没有考虑的关于对称块算法和填充的内容(或者您可能已经考虑过,它与这个问题根本无关)。
像 Blowfish 这样的对称块算法在块大小上运行。对于 Blowfish,块大小为 64位(8 字节)。这意味着加密/解密操作总是发生在 64 位大小的块中。如果您使用的是较低级别的 openssl api,则必须加密(和解密)不大于该数据的块中的数据。更高级别的 API(例如BF_cfb64_encrypt
)旨在允许“流模式”,这意味着您可以以更大的块提交数据,只要它们的大小是块大小的倍数。并且您在对 API 的链式连续调用之间保留iv
和值。n
最后,我开始写这篇关于对称块算法和填充模式的相当长的文章,但意识到这并不适合这个问题,所以我只能建议你研究一下。我怀疑你在某个时候需要这样做。