2009-10-01 4 views
2

J'essaie d'utiliser les fonctions BN_ * dans OpenSSL. Plus précisément, j'ai le code suivant:Problème avec la fonction BN_bn2bin d'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); 

Cependant, quand je le fais, je ne suis pas une chaîne de uns et de zéros. Au lieu de cela, il imprime "42 in binary is *". Pour autant que je sache, et à partir du très nombre limité d'exemples disponibles sur le Web que j'ai comparé à, j'ai implémenté correctement.

Des idées pour lesquelles cela ne fonctionne pas?

Répondre

6

BN_bn2bin ne crée pas de chaîne imprimable - à la place, elle crée une représentation qui est réellement binaire Plus précisément, il crée une représentation big-endienne du nombre. Puisque 42 correspond à un octet, vous obtenez un octet 0x2a, qui est "*" en ASCII.

Si vous voulez une représentation 0/1, vous devez parcourir tous les octets et effectuer vous-même l'impression (par exemple, avec un décalage ou une table de correspondance).

+0

doh! J'aurais dû penser à regarder la valeur ASCII! Je supposais que, comme il est indiqué dans les documents à côté de bn2hex et bn2dec que cela fonctionnerait de la même manière. Bummer ... Merci d'avoir clarifié. =) –

0

Voici un code qui transforme la sortie BN_bn2bin en une chaîne imprimable, tout comme la sortie de BN_bn2dec et BN_bn2hex. C'est dans une bibliothèque NodeJS mais est écrit en C++ pour la vitesse. Il m'a pris toute la journée et n'est probablement pas optimal (parce que je n'ai pas écrit de code C++ depuis la première année d'uni). Mais il passe un tas de tests unitaires donc je sais que ça marche!

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); 
} 
Questions connexes