2016-07-14 7 views
0

私は、このOpenSSLコードをiPhoneで使用して、証明書/秘密鍵のデータがある場合、PKCS#12ファイルを生成しています。私は、このPKCS#12がOpenSSL上で解析可能であることを検証することができます。なぜなら、コードでチェックするとエラーを出力しないからです。しかし、私は私のサーバーに転送するとき、それは言う:Error: PKCS#12 MAC could not be verified. Invalid password?誰がなぜこれは知っていますか?ここで はJavascriptで書かれた私のサーバー側のコードです:私は「パスワード」PKCS#12無効なパスワード

- (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で同じパスワードを使用しています。この場合、req.bodyはiPhoneから送信されたNSDataです。無効なパスワードエラーが表示されます。

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

NSDataラインを変更するだけで問題を解決できますか?バイナリデータをbase64でエンコードできないのですか? – hockeybro

+0

これは、 'openssl pkcs12 -in p12.p12 -nocerts -out privateKey.pem'をシェルで実行するときに発生します。パスワードを要求し、パスワードを入力するとそのエラーが発生します。 p12.p12はその中にデータを持つファイルです。私はそれを作成するために別の関数を使いました。それは別の形式でテストしてから機能します。 – hockeybro

+0

元の投稿を編集しました。上記の「コード」で私は誤った取り扱いをしていますが、どのように修正することができますか? – hockeybro

答えて

1

以下を試してください。これは、いくつかの重要な戻り値をチェックする必要がありますを示しており、それは、データの余分なコピーを避ける:

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

あなたはi2d_PKCS12_bio man pagesi2d_PKCS12_bioのためのドキュメントを見つけることができます。

必要に応じて、i2d_PKCS12_bioのバイナリデータをBase64でエンコードできます。 BIOチェーンを使用し、Base64文字列がNULLで終了することを確認するには、Non-printable character after generating random n-byte Base64 stringを参照してください。

関連する問題