【问题标题】:Blowfish CBC mode and Buffer Overrun in CBlowfish CBC 模式和 C 中的缓冲区溢出
【发布时间】:2016-09-13 04:29:09
【问题描述】:

我正在尝试使用 OpenSSL 库使用 Blowfish 的 CBC 块模式加密和解密字符串。由于平台原因,这需要在直接 C 而不是 C++ 中完成。由于某种原因,当输入字符串长于 8 个字符(1 个块)时,输出的大小会急剧增加。

例如:加密 abcdefgh 将生成一个长度为 8 个字符的输出 - 一切都很好。但是,加密 abcdefgha 将生成 699 个字符长的输出!

我在这个库上做错了什么吗?我的理解是 Blowfish 的输出应该与输入的大小相同。谁能解释我做错了什么?如果这是正确的,我怎么知道创建输出缓冲区有多大,因为当输入超过 1 个块时,这段代码会超出它。

下面的代码示例:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/blowfish.h>
const unsigned char* BLOWFISH_KEY = "TestKey!";
#define SIZE 8

unsigned char* blowfish_decrypt(unsigned char* in);
unsigned char* blowfish_encrypt(unsigned char* in);

int main(){

    char* message   = "abcdefgha";

    char* encrypted = blowfish_encrypt(message);
    printf("Encrypted: %s\n", encrypted);
    printf("Size of encrypted: %d\n\n", strlen(encrypted));

    char* decrypted = blowfish_decrypt(encrypted);
    printf("Decrypt: %s\n", decrypted);
    printf("Size of encrypted: %d\n\n", strlen(encrypted));
    return 0;

}

unsigned char* blowfish_encrypt(unsigned char* in){

  int i;
  int SIZE_IN = strlen(in);
  unsigned char *out = calloc(SIZE_IN+1, sizeof(char));

  char ivec[8];
  for(i=0; i<8; i++) ivec[i] = 'i';

  BF_KEY *key = calloc(1, sizeof(BF_KEY));

  /* set up a test key */
  BF_set_key(key, SIZE, BLOWFISH_KEY );

  BF_cbc_encrypt(in, out, strlen(in), key, ivec, BF_ENCRYPT);

  printf("Size of out: %d\n", strlen(out));
  printf("Size of in: %d\n", strlen(in));
  return out;
}

unsigned char* blowfish_decrypt(unsigned char* in){

  int i;
  int SIZE_IN = strlen(in);
  unsigned char *out = calloc(SIZE_IN+1, sizeof(char));

  char ivec[8];
  for(i=0; i<8; i++) ivec[i] = 'i';

  BF_KEY *key = calloc(1, sizeof(BF_KEY));

  /* set up a test key */
  BF_set_key(key, SIZE, BLOWFISH_KEY );

  BF_cbc_encrypt(in, out, strlen(in), key, ivec, BF_DECRYPT);

  printf("Size of out: %d\n", strlen(out));
  printf("Size of in: %d\n", strlen(in));
  return out;
}

【问题讨论】:

    标签: c encryption openssl blowfish


    【解决方案1】:

    当您的输入字符串被加密时,生成的数据不再是您可以使用strlen() 来获取其长度的字符串。您只能将数据视为二进制流。

    由于 Blowfish 是分组密码,因此您必须确保输入是分组大小的倍数,并且如果输入长度不合适,您必须注意填充。当您为简单测试进行适当的填充时,输出长度与您的输入相同。

    您可以使用更高级别的 EVP 加密/解密函数http://linux.die.net/man/3/evp_encryptinit,默认启用填充。

    【讨论】:

    • 非常感谢!是块大小让我感到震惊。我将 strlen 插入进行调试 - 我之前使用 Base64 对结果进行编码,结果得到了一个相当大的字符串。
    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2015-12-16
    相关资源
    最近更新 更多