2

我正在尝试在 OpenSSL 中使用 BN_* 函数。具体来说,我有以下代码:

#import <openssl/bn.h>
BIGNUM * num = BN_new();
BN_set_word(num, 42);
char * buffer = malloc((BN_num_bytes(num)+1) * sizeof(char));
buffer[BN_num_bytes(num)] = '\0';
int len = BN_bn2bin(num, buffer);
printf("42 in binary is %s\n", buffer);

但是,当我这样做时,我没有得到一串 1 和 0。相反,它打印"42 in binary is *". 据我所知,从我比较过的网络上非常有限的例子来看,我已经正确地实现了这一点。

任何想法为什么它不起作用?

4

2 回答 2

6

BN_bn2bin不会创建可打印的字符串 - 相反,它会创建真正的二进制表示(即位序列)。更具体地说,它创建数字的大端表示。由于 42 适合 1 个字节,因此您得到 1 个字节 0x2a,即 ASCII 中的“*”。

如果您想要 0/1 表示,您需要遍历所有字节,并自己进行打印(例如,使用移位或查找表)。

于 2009-10-01T21:38:50.387 回答
0

这里有一些代码实际上将BN_bn2bin输出转换为可打印的字符串,就像BN_bn2decand的输出一样BN_bn2hex。它在 NodeJS 库中,但为了速度是用 C++ 编写的。花了我一整天,可能不是最佳的(因为自大学第一年以来我没有编写任何 C++ 代码)。但它通过了一堆单元测试,所以我知道它有效!

https://github.com/malcolmocean/node-bignum

if (BN_is_zero(&bignum->bignum_)) {
  to = (char*) OPENSSL_malloc(2*sizeof(char));
  to[0] = '0';
  to[1] = '\0';
} else {
  unsigned char *binary = (unsigned char*) OPENSSL_malloc(BN_num_bytes(&bignum->bignum_)*sizeof(unsigned char));
  int len = BN_bn2bin(&bignum->bignum_, binary);
  to = (char*) OPENSSL_malloc((len*8+2)*sizeof(char));
  int offset = 0;
  if (BN_is_negative(&bignum->bignum_)) {
    to[0] = '-';
    offset--;
  }
  unsigned char x = binary[0];
  while (!(x & 128) && x) {
    x = x << 1;
    offset++;
  }
  for (int i = 0; i < len; i++) {
    unsigned char bits = binary[i];

    int j=7;
    while(bits) {
      if (bits & 1) {
        to[8*i+j-offset] = '1';
      } else {
        to[8*i+j-offset] = '0';
      }
      bits = bits >> 1;
      j--;
    }
    if (i > 0) {
      while (j >= 0) {
        to[8*i+j-offset] = '0';
        j--;
      }
    }
  }
  to[8*len-offset] = '\0';
  OPENSSL_free(binary);
}
于 2015-10-31T06:00:09.107 回答