Проблема с функцией OpenSSL BN_bn2bin - PullRequest
2 голосов
/ 02 октября 2009

Я пытаюсь использовать функции BN_ * в OpenSSL. В частности, у меня есть следующий код:

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

Однако, когда я делаю это, я не получаю строку из нулей и единиц. Вместо этого он печатает "42 in binary is *". Насколько я могу судить, и из очень ограниченного числа примеров, доступных в сети, с которыми я сравнивал это, я правильно реализовал.

Есть идеи, почему это не работает?

Ответы [ 2 ]

6 голосов
/ 02 октября 2009

BN_bn2bin не создает печатаемой строки - вместо этого он создает действительно двоичное представление (то есть последовательность битов). Более конкретно, он создает представление числа с порядком байтов. Поскольку 42 помещается в один байт, вы получаете один байт 0x2a, который в ASCII равен "*".

Если вы хотите представление 0/1, вам нужно перебрать все байты и выполнить печать самостоятельно (например, со сдвигом или таблицей поиска).

0 голосов
/ 31 октября 2015

Вот некоторый код, который на самом деле превращает вывод BN_bn2bin в печатаемую строку, как вывод BN_bn2dec и 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);
}
...