Setting up Apple Pay is a simple process when using a payment processor that accepts Apple Pay (Square, Stripe, ect).

  • Create a merchant ID
  • Upload a certificate signing request given by the payment processor into the Apple Developer Portal
  • Upload the Apple generated payment processing certificate into the payment gateway’s portal
  • Enable Apple Pay in the app’s configuration

Done, nothing particularly difficult about it.

It becomes tricky when your payment processor does not accept Apple Pay and you need to decrypt your own Apple Payment Tokens.

Not only is there a LOT of cryptography involved but you also have to create and manage your own certificate signing requests and generated certificates and keys securely. Did I mention that they expire? :P

Something that can tend to be insecure is a random developer’s or client’s Mac. Apple’s documentation for creating a Certificate Signing Request for Apple Pay involves using MacOS’s keychain program. Because of this, a lazier or more naive developer may quickly create a CSR (Certificate Signing Request) straight away from their own machine without thinking about the security implications. Maybe said developer even forget’s to delete the file’s off of his computer or out of their local keychain. Any compromise to the machine could possibly compromise all the Apple Pay transactions sent for that merchant identifier.

An ideal scenario would be to generate the CSR on a known hardened machine, preferably ephemeral. Unfortunately ephemeral machines tend not to be MacOS’s.

What would be great is if Apple had detailed documentation on creating said CSR as well as other required decryption artifacts using openssl on the command line. Then we would not be bound to MacOS or OSX.

I am no crypto guru or openssl expert so I came to the solution through Google-foo and stubbornness. I will do my best to explain what is going on in each command.

First we will generate the private key for our CSR,

openssl ecparam -out private.key -name prime256v1 -genkey

Apple specifies the CSR should be use ECC (why we use the ecparam command) as well as having a key length of 256 (why we have prime256v1).

This command creates the key for our CSR, next we will create the CSR itself.

openssl req -new -sha256 -key private.key -nodes -out request.csr

After creating our request.csr simply upload the file into the Apple Developer Portal associating it to the correct Merchant Identifier for your application.

Apple will then hand us back a .cer file in return. That certificate combined with a PKCS #12 file (.p12 file extension) allow us to actually verify the Apple Payment Token’s signature and decrypt it’s payload so we can process the transaction ourselves or pass it along to our payment processor that does not support Apple Pay.

Back to the command line foo.

openssl x509 -inform DER -outform PEM -in apple_pay.cer -out temp.pem

Here we are create a .pem file from the apple_pay.cer Apple gave us. We will use it to generate our .p12 file.

openssl pkcs12 -export -out key.p12 -inkey private.key -in temp.pem

This is the final required command, it is generating a .p12 file based off of the original CSR .key file as well as the temp.pem file we just created.

After running the command it will prompt you for a password to protect the .p12 file with. This should be a strong safely guarded password since it is a key to decrypting payment data.

After this has been completed we have the 3 ingredients required to decrypt any Apple Payment Token generated for any app using the associated Merchant Identifier.

1) apple_pay.cer

the payment processing certificate Apple gave us

2) key.p12

the generated PKCS #12 file based off of our original CSR key and the Apple Payment Processing Certificate

3) password

the password to our key.p12 file

If you are stuck decrypting your own Apple Payment Token’s I hope this short guide will help you secure the Apple Pay Certificate Signing Request process as well as the sensitive decryption artifacts it creates.

Cheers!