OpenSSL 的 BN_bn2bin 函数出现问题

发布于 2024-08-06 05:00:16 字数 451 浏览 1 评论 0原文

我正在尝试在 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 是 *”。据我所知,从我与之比较的网络上可用的非常有限的示例来看,我已经正确实现了这一点。

有什么想法为什么它不起作用吗?

I'm trying to use the BN_* functions in OpenSSL. Specifically, I have the following code:

#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);

However, when I do this, I don't get a string of ones and zeros. Instead it prints "42 in binary is *". As far as I can tell, and from the very limited number of examples available on the web that I've compared this to, I've implemented this correctly.

Any ideas why it isn't working?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花伊自在美 2024-08-13 05:00:16

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

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

BN_bn2bin doesn't create a printable string - instead, it creates a representation that is truly binary (i.e. a sequence of bits). More specifically, it createas a big-endian representation of the number. Since 42 fits into one byte, you get one byte 0x2a, which is "*" in ASCII.

If you want a 0/1 representation, you need to iterate over all bytes, and do the printing yourself (e.g. with shifting or a lookup table).

岁月静好 2024-08-13 05:00:16

下面的一些代码实际上将 BN_bn2bin 输出转换为可打印字符串,就像 BN_bn2decBN_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);
}

Here's some code that actually turns the BN_bn2bin output into a printable string just like the output of BN_bn2dec and BN_bn2hex. It's in a NodeJS library but is written in C++ for speed. Took me all day and probably isn't optimal (because I haven't written any C++ code since first year of uni). But it passes a bunch of unit tests so I know it works!

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文