title: PKCS#12 Invalid Password
body: <p>I am using this OpenSSL code on the iPhone to generate a PKCS#12 file given some data of a certificate/private key. I am able to verify that this PKCS#12 is parseable on OpenSSL, since it doesn't print out an error when I check for it in the code. However, when I transfer it to my server, it says: <code>Error: PKCS#12 MAC could not be verified. Invalid password?</code> Does anyone know why this is? I am using the same password, which is 'password'</p>
  
  <pre><code> - (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, &amp;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(&amp;rsa, &amp;bits, &amp;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", &amp;parseKey, &amp;parseCert, &amp;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, &amp;buffer);
  
      //int bioLen = BIO_pending(&amp;buffer);
  
  
      char *buff = (char*)malloc(buffer-&gt;length);
      memcpy(buff, buffer-&gt;data, buffer-&gt;length - 1);
      buff[buffer-&gt;length - 1] = 0;
      NSData *data = [NSData dataWithBytes:buff length:buffer-&gt;length];
  
      NSString *string = [data base64EncodedStringWithOptions:0];
      NSLog(@"Base64 PKCS#12: %@", string);
  
      BIO_free_all(bio);
  
      return data;
  }
  </code></pre>
  
  <p>EDIT:
  Here is the code on my server side written in Javascript. In this case req.body is the NSData sent from the iPhone. I get the invalid password error.   </p>
  
  <pre><code>  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');
  </code></pre>