Recover signing certificate without p12 password?

Mitch Cohen picture Mitch Cohen · Apr 21, 2013 · Viewed 19.9k times · Source

I've been handed an iOS app codebase, which I'd like to distribute via the existing Enterprise certificate used by the prior developer.

After importing the provided .mobileprovision file, I'm (not unsurprisingly) getting the "Valid signing identity not found" error. Specifically when building:

The identity '[name]' doesn't match any valid, non-expired certificate/private key pair in your keychains

I was given the original CertificateSigningRequest.certSigningRequest file, a .p12 file, and the .cer file. I was not given the password to the .p12 file.

Is it possible to rebuild what I need from the CertificateSigningRequest.certSigningRequest without the .p12 file's password? I can likely get the .p12 password, but not in a timely manner.

Thanks!

Answer

Bryan Musial picture Bryan Musial · Apr 29, 2013

I recognize that you've solved your issue by getting the password for the .p12 file, but I thought I'd shine a little light on what lives in each of those files you mentioned for the benefit of anyone running across the question in the future.

To answer the main question in this question: Can I rebuild what I need from the CertificateSigningRequest.certSigningRequest file?

Regrettably the answer is a very solid 'No'. The root cause of this is the very heart of Public Key Infrastructure (PKI), a set of management technologies, people, and practices dealing with the creation, verification, use, and revocation of digital certificates. Central to PKI is the notion of a public-private key pair. The 'Public' key is the one you share widely, anyone may have a copy of it and anyone wishing to validate messages signed by a digital certificate will require access to this key. The 'Private' key is the linked key that only you (or more accurately, your machine) knows and uses when signing messages. It is this signature that is verified via use of the 'Public' key that is shared widely authenticating that the message is in fact authentic.

When we are constructing development or distribution certificates, we are inherently asking Keychain Access, openssl, or your preferred SSL toolchain to create a public-private key pair. The public key goes into the CertificateSigningRequest file along with the other 'Subject' fields like name and email address and we ship this file off to Apple. That file primarily tells Apple what Public Key they can use to validate your app signature -- it does not give them a copy of your Private Key after all, if others had your private key they'd be able to codesign as you effectively destroying the notion of accountability on the iOS platform (ex. This App's signature checks out as valid, but I still don't know if it was actually signed by a developer I trust...). At no point in time, is your Private Key transmitted to Apple or the Developer Portal; it resides quite happily in your Keychain until such a time as 1) The certificate expires, 2) you actively revoke the certificate from the Developer Portal, or 3) you accidentally (or intentionally) delete the keypair from Keychain.

So what lives in each of these files?

CertificateSigningRequest.certSigningRequest - This contains a copy of the Public Key from the Public-Private keypair you generated locally, plus some additional required subject information required by the Certificate Signing Request format. Apple disregards this additional information and uses the name and email address they have on file for your Developer Account when constructing your certificate.

.p12 - This is a PKCS#12 formatted file containing a copy of the Apple-issued Certificate (which itself contains the Public Key) and a copy of the linked Private Key. This data is encrypted to prevent unauthenticated access and thus requires a password to decrypt.

.cer - This is the Apple-issued Certificate that contains the Public key portion of the key pair. This certificate is used by Apple to validate that Apps you submit are not tampered with while in transit to the App Store review team:

  • You sign your app using the Private key that only you know and upload the signed binary to Apple.
  • Apple then validate the signature using the public key that you've already shared with them.
    • If the math works out, then the App hasn't been tampered with and you are good to go.
    • If the math doesn't work out, either the app was tampered with, or (much more likely) the certificate was revoked or regenerated and the app was signed with an old or incorrect key pair.

As you can see, the only places the Private Key resides is in the original developer's keychain as well as the encrypted .p12 file. Consistent with both your comment and flup's comment, you either have to get the password to that .p12 file or look into breaking through the encryption.

Regardless, good to hear that you were able to get the password from the original developer. Let me know if you have any followup questions.