2012-03-10 42 views
7

Tôi đang sử dụng openssl để lấy dữ liệu về chứng chỉ x509. Có cách nào để chuyển đổi ASN1_INTEGER thành ASN1_STRING, có thể dễ dàng chuyển thành mảng char không? Có cách nào để chuyển đổi nó sang bất kỳ định dạng nào khác có thể đọc được của con người không?ASN1_INTEGER to ASN1_STRING

EDIT: Tôi đang sử dụng openssl được biên dịch cho iOS, vì tôi đang có dự án iOS. Đây là mã tôi đang sử dụng để trích xuất các số serial từ chứng chỉ:

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

certificateX509 là một đối tượng X509 có giá trị và tôi đã được quản lý để có được một số lĩnh vực khác từ nó (tên tổ chức phát hành, thời hạn sử dụng và vân vân)

EDIT 2:
cuối cùng tôi đã đến một giải pháp, trong đó có thể không phải là đơn giản nhất:

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 sau đó chứa các ký tự có giá trị cần được đọc như nguyên hex trong orde r để lấy các giá trị logic. tôi sử dụng NSMutableString để tạo ra một chuỗi có thể đọc được con người:

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

Nếu có một cách đơn giản hơn, tôi thực sự muốn biết điều đó.

Trả lời

2

cuối cùng tôi đã đến một giải pháp, trong đó có thể không phải là đơn giản nhất:

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 sau đó chứa các ký tự có giá trị cần được đọc như nguyên hex để lấy giá trị logic. tôi sử dụng NSMutableString để tạo ra một chuỗi có thể đọc được con người:

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

Một khả năng là bạn có thể trích xuất các giá trị của ASN1_INTEGER như một C nguyên bình thường:

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

Biên soạn như thế này:

gcc -Wall -o sploots sploots.c -lcrypto 

này tạo ra kết quả:

The value is 42. 

Để có giá trị dưới dạng một chuỗi trong một mảng char, hãy sử dụng snprintf.

Tôi nghi ngờ cũng có khả năng sử dụng các thói quen in ấn BIO để đổ giá trị vào BIO của một số loại (có lẽ là một BIO bộ nhớ). Tuy nhiên, cách tiếp cận này có vẻ đơn giản hơn.

Cách tôi đến câu trả lời này là tôi đã xem qua các tiêu đề OpenSSL cho ASN1_INTEGER. Sau khi tìm kiếm các API phù hợp cho giải pháp dựa trên BIO, tôi nhận thấy hàm ASN1_INTEGER_get.

Nhìn xung quanh trong các tệp tiêu đề OpenSSL thường là cách tôi tìm hiểu cách sử dụng OpenSSL, vì rất nhiều API không có tài liệu hoặc không chính xác hoặc không đầy đủ tài liệu.

+0

Không chắc chắn về những gì anh ấy hỏi, nhưng đối với số sê-ri chứng chỉ, điều này có thể không hữu ích. Ví dụ: tôi đã kiểm tra một chứng chỉ và số sêri là "3c 08 cf ee là 9f eb c4 2b b1 3e e0 3d 62 0b df". Đúng là không có cách nào khác ngoài việc mở các tệp tiêu đề và tìm hiểu thông tin. –

+0

bạn đúng, điều đó không hiệu quả với tôi. Tôi luôn nhận được -1 là một giá trị dài – Maggie

+0

Có vẻ như bạn không nhận được ASN1_INTEGER trong số chứng chỉ. Có lẽ đó là một BIGNUM? Bạn có thể thêm mã bạn đã sử dụng để trích xuất nó từ chứng chỉ cho câu hỏi không? –

10

Việc chuyển đổi hex ascii được thực hiện đơn giản hơn bằng cách sử dụng được xây dựng trong BN_bn2hex (bignum *) chức năng

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

Nếu bạn chỉ muốn một NSString có thể đọc được , BN_bn2dec hợp lý hơn BN_bn2hex hoặc BN_bn2bin.
Không cần phải gây rối với mã hóa hex.

Dưới đây là cách của tôi, trong iOS/ObjC, sử dụng 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.