2012-03-10 10 views
7

Używam openssl, aby uzyskać dane o certyfikacie x509. Czy istnieje sposób przekonwertowania ASN1_INTEGER na ASN1_STRING, który można łatwo przekształcić w tablicę znaków? Czy istnieje sposób na przekonwertowanie go do dowolnego formatu czytelnego dla człowieka?ASN1_INTEGER do ASN1_STRING

EDYCJA: Używam openssl skompilowany dla iOS, ponieważ mam projekt iOS. Oto kod używam wyodrębnić numer seryjny certyfikatu:

ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509); 
long value = ASN1_INTEGER_get(serial); 
NSLog(@"Serial %ld", value); 

certificateX509 jest poprawnym obiektem X509 i udało mi się dostać jakieś inne pola z nim (nazwa emitenta, datę ważności i tak dalej)

EDIT 2:
I w końcu przyszedł do rozwiązania, które nie mogą być najprostszym jeden:

ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509); 
BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL); 
int n = BN_num_bytes(bnser); 
unsigned char outbuf[n]; 
int bin = BN_bn2bin(bnser, outbuf); 
char *hexbuf = (char*) outbuf; 

hexBuf następnie zawiera znaki, których wartość musi być odczytywane jako hex liczby całkowitej w Orde r, aby pobrać wartości logiczne. używam NSMutableString stworzyć czytelny dla człowieka napis:

NSMutableString *str = [[NSMutableString alloc] init]; 
for (int i=0; i<n; i++) { 
    NSString *temp = [NSString stringWithFormat:@"%.6x", hexbuf[i]]; 
    [str appendString:[NSString stringWithFormat:@"%@ ", temp]]; 
} 

Jeśli istnieje prostszy sposób, naprawdę chciałbym to wiedzieć.

Odpowiedz

2

I w końcu przyszedł do roztworu, który nie może być najprostszym jeden:

ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509); 
BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL); 
int n = BN_num_bytes(bnser); 
unsigned char outbuf[n]; 
int bin = BN_bn2bin(bnser, outbuf); 
char *hexBuf = (char*) outbuf; 

hexBuf następnie zawiera znaki, których wartość musi być odczytywane jako hex liczby całkowitej w celu pobrania wartości logicznych. używam NSMutableString stworzyć czytelny dla człowieka napis:

NSMutableString *str = [[NSMutableString alloc] init]; 
    for (int i=0; i<n; i++) { 
    NSString *temp = [NSString stringWithFormat:@"%.6x", hexbuf[i]]; 
    [str appendString:[NSString stringWithFormat:@"%@ ", temp]]; 
} 
5

Jedną z możliwości jest to, że można wyodrębnić wartość ASN1_INTEGER jako normalny C integer:

#include <openssl/asn1.h> 
#include <stdio.h> 

int main(int argc, char** argv) { 
    long value; 
    ASN1_INTEGER asn1int = {0}; 

    ASN1_INTEGER_set(&asn1int, 42); 
    value = ASN1_INTEGER_get(&asn1int); 
    printf("The value is %ld.\n", value); 

    return 0; 
} 

skompilowany tak:

gcc -Wall -o sploots sploots.c -lcrypto 

To daje wynik:

The value is 42. 

Aby mieć wartość jako ciąg znaków w tablicy znaków, należy użyć snprintf.

Podejrzewam, że istnieją również możliwości wykorzystania procedur drukowania BIO do zrzucenia wartości do BIO jakiegoś rodzaju (być może BIO pamięci). Takie podejście wydaje się jednak prostsze.

Sposób, w jaki doszedłem do tej odpowiedzi, to przeglądanie nagłówków OpenSSL dla ASN1_INTEGER. Po rozejrzeniu się za odpowiednimi API dla rozwiązania opartego na BIO, zauważyłem funkcję ASN1_INTEGER_get.

Rozglądanie się w plikach nagłówkowych OpenSSL jest zazwyczaj sposobem, w jaki uczę się korzystać z OpenSSL, ponieważ wiele funkcji API jest nieudokumentowanych lub niepoprawnie lub niecałkowicie udokumentowanych.

+0

Nie jesteś pewien, o co pyta, ale w przypadku numerów seryjnych certyfikatów prawdopodobnie nie jest to zbyt przydatne. Na przykład, sprawdziłem jeden certyfikat i numer seryjny to "3c 08 cf ee be 9f eb c4 2b b1 3e e0 3d 62 0b df". To prawda, że ​​nie ma innego wyjścia, jak tylko otwarcie plików nagłówkowych i wykopanie informacji. –

+0

masz rację, to nie działa dla mnie. Zawsze otrzymuję -1 jako długą wartość – Maggie

+0

Wygląda na to, że nie dostajesz ASN1_INTEGER z certyfikatu. Może to BIGNUM? Czy możesz dodać kod użyty do wyodrębnienia go z certyfikatu na pytanie? –

10

ASCII konwersja hex zrobić prościej za pomocą wbudowanego w BN_bn2hex (BIGNUM *) funkcję

ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509); 
BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL); 
char *asciiHex = BN_bn2hex(bnser); 
1

Jeśli chcesz tylko czytelny NSString , BN_bn2dec jest bardziej kompaktowy niż BN_bn2hex lub BN_bn2bin.
Nie trzeba robić bałaganu z kodowaniem szesnastkowym.

Oto mój sposób, w iOS/ObjC korzystając pod 'OpenSSL-Universal', '1.0.2.10':

ASN1_INTEGER *serialAsn1 = X509_get_serialNumber(certX509); 
BIGNUM *serialBigNumber = ASN1_INTEGER_to_BN(serialAsn1, NULL); 
char *serialChar = BN_bn2dec(serialBigNumber); 

NSString *serialString = [NSString stringWithCString:(const char *) serialChar 
              encoding:NSUTF8StringEncoding]; 

Cheers.