2016-07-14 17 views
0

Ich verwende diesen OpenSSL-Code auf dem iPhone, um eine PKCS # 12-Datei mit einigen Daten eines Zertifikats/privaten Schlüssels zu erzeugen. Ich bin in der Lage zu überprüfen, dass dieser PKCS # 12 auf OpenSSL analysierbar ist, da es einen Fehler nicht ausgibt, wenn ich es in dem Code überprüfe. Jedoch, wenn ich es auf meinen Server übertrage, heißt es: Error: PKCS#12 MAC could not be verified. Invalid password? Weiß jemand, warum das ist? Ich bin mit dem gleichen Passwort, das ‚Passwort‘PKCS # 12 Ungültiges Passwort

- (NSData *)generateP12AsNSData:(NSData *)keyData certificate:(NSData *)certificateData { 
    //put the certificateData into a X509 certificate 
    const unsigned char *certificateDataBytes = (const unsigned char*)[certificateData bytes]; 
    X509 *certificateX509 = d2i_X509(NULL, &certificateDataBytes, [certificateData length]); 

    EVP_PKEY *privateKey; 
    PKCS12 *p12; 
    //cast the key data as an unsigned char so that we can convert it to the OpenSSL key format 
    const unsigned char *bits = (unsigned char *) [keyData bytes]; 
    int length = (int)[keyData length]; 
    privateKey = EVP_PKEY_new(); 

    //convert the unsigned char to OpenSSL Key format 
    RSA *rsa = NULL; 
    d2i_RSAPrivateKey(&rsa, &bits, &length); 
    EVP_PKEY_assign_RSA(privateKey, rsa); 

    //create the PKCS#12 
    OpenSSL_add_all_algorithms(); 
    p12 = PKCS12_create("password", "ExtraDeviceP12", privateKey, certificateX509, NULL, 0,0,0,0,0); 

    //make sure the p12 exists 
    if(!p12) { 
     fprintf(stderr, "Error creating PKCS#12 "); 
     ERR_print_errors_fp(stderr); 
     return nil; 
    } 

    //error checking to make sure we generated the CSR correctly 
    STACK_OF(X509) *ca = NULL; 
    EVP_PKEY *parseKey; 
    X509 *parseCert; 
    if (!PKCS12_parse(p12, "password", &parseKey, &parseCert, &ca)) { 
     printf("error parsing PKCS#12 file"); 
     return nil; 
    } 

    //convert the PKCS#12 to binary data 
    //create a new memory BIO. A BIO is used for basic I/O abstraction. 
    BIO *bio; 
    bio = BIO_new(BIO_s_mem()); 
    //i2d_PKCS12_bio is used to export a PKCS12 object 
    i2d_PKCS12_bio(bio, p12); 
    BUF_MEM *buffer; 
    BIO_get_mem_ptr(bio, &buffer); 

    //int bioLen = BIO_pending(&buffer); 


    char *buff = (char*)malloc(buffer->length); 
    memcpy(buff, buffer->data, buffer->length - 1); 
    buff[buffer->length - 1] = 0; 
    NSData *data = [NSData dataWithBytes:buff length:buffer->length]; 

    NSString *string = [data base64EncodedStringWithOptions:0]; 
    NSLog(@"Base64 PKCS#12: %@", string); 

    BIO_free_all(bio); 

    return data; 
} 

EDIT ist: Hier ist der Code auf meiner Server-Seite in Javascript geschrieben. In diesem Fall ist req.body die vom iPhone gesendete NSData. Ich erhalte den ungültigen Passwortfehler.

var p12b64 = req.body.toString('base64');  
    var p12Der = forge.util.decode64(pk12b64); 
    var p12Asn1 = forge.asn1.fromDer(p12Der); 
    var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, 'password'); 
+0

Wird nur das Ändern der NSData-Linie das Problem beheben? Kann ich die Binärdaten nicht als Base64 codieren? – hockeybro

+0

Es kommt, wenn ich 'openssl pkcs12 -in p12.p12-nocerts-out privateKey.pem' in der Shell ausführen. Es fragt nach einem Passwort und es verursacht diesen Fehler bei der Eingabe des Passworts. p12.p12 ist eine Datei, in der die Daten enthalten sind. Ich habe eine andere Funktion verwendet, um es zu erstellen, und das funktioniert, seit ich mit einem anderen Format getestet habe. – hockeybro

+0

Ich habe den ursprünglichen Beitrag bearbeitet. Was missbrauche ich im "Code oben" und wie kann es behoben werden? – hockeybro

Antwort

1

Versuchen Sie Folgendes. Es zeigt Ihnen, wo einige der wichtigsten Rückgabewerte überprüft werden sollen, und es vermeidet zusätzliche Kopien der Daten:

BIO *bio = BIO_new(BIO_s_mem()); 
ASSERT(bio != NULL); 

int ret = i2d_PKCS12_bio(bio, p12); 
ASSERT(ret == 1); 

BUF_MEM *buffer; 
BIO_get_mem_ptr(bio, &buffer); 
ASSERT(buffer != NULL); 

NSData *data = [NSData dataWithBytes:buffer->data length:buffer->length]; 
BIO_free_all(bio); 

Sie die Dokumentation für i2d_PKCS12_bio bei i2d_PKCS12_bio man pages finden. Wenn Sie möchten, können Sie Base64 die Binärdaten von i2d_PKCS12_bio codieren. Siehe Non-printable character after generating random n-byte Base64 string, um eine BIO-Kette zu verwenden und sicherzustellen, dass die Base64-Zeichenfolge NULL-terminiert ist.

Verwandte Themen