I'm trying to configure my iOS app to receiver notifications with Firebase.
If I export the certificate and the private key without a password and try to upload it (production or development) on Firebase console I get the error "Incorrect password".
If I export the certificate and the private key with a password I get the error "An unknown server error ocurred" or "There was an error reading your certificate".
I don't understand why that is happening. I did follow the tutorial correctly. Can someone help me?
You should be using an APNS Authentication Key rather than the certificates. This is the new preferred method in iOS for a provider to register and send messages with APNS
From Firebase:
Configuration with auth keys is recommended as they are the more
current method for sending notifications to iOS
From Apple:
For a provider to communicate with APNs, it must employ a valid
authentication key certificate (for token-based connection trust) or
SSL certificate (for certificate-based connection trust). You obtain
either of these certificates from your online developer account, as
explained in “Configure push notifications” in Xcode Help. To choose
between the two certificate types, read Provider-to-APNs Connection
Trust. Whichever certificate type you choose, provider connection
trust is prerequisite to a provider sending push notification requests
to APNs.
while exporting just select the Apple Push Service part and don't select the private key from Keychain Access and export than in firebase Production APNs certificate browse the p12 file you just created, it will work.
I don't know when this implementation will be deprecated but it works as of now (19 Feb 2018).
You should export only the certificate and don't select the private key . Please see this screenshot
Related
If a user has uninstalled my app, how long will the APNS take to update that this device is inactive for the bundleID?
Heyo, after reading up a bunch to make the migration to the new APNS provider API, this is what seems most familiar to me regarding this:
Establishing a Certificate-Based Connection to APNs
"Check expiry of a certificate with KeyChain Access. To avoid a disruption in service for your users, update your provider certificates before they expire. Provider certificates are valid for a year and must be updated to continue communicating with APNs".
Also:
"If you think your certificate or private key has been compromised, you can revoke your certificate from your developer account. APNs maintains a list of revoked certificates, and it refuses TLS connections from servers whose certificates are on that list. If your server is using a revoked certificate, close all existing connections to APNs and configure a new provider certificate for your server before opening any new connections".
Seems to me it the expiry is based around certificate creation as well as deleting the app?
I'd like to hear more on this....
I'm reading this article on iOS push certificates, and I'm confused about this paragraph:
Your backend sends notifications through Apple's servers to your application. To ensure that unwanted parties are not sending notifications to your application, Apple needs to know that only your servers can connect with theirs. Apple therefore requires you to create an SSL certificate to be able to send push notifications.
My understanding of SSL certificates is that if a server has one, that server is able to encrypt data that it sends to a device. But it says here Apple needs to know that only your servers can connect with theirs. I don't understand how having an SSL certificate ensures that. Does anyone have any insight?
The article shouldn't have used the term SSL Certificate. SSL is the Secure Sockets Layer (which was superseded by TLS many years ago). SSL and TLS define the handshake that is used to negotiate encryption on a connection.
Enabling SSL on a web server required you to have a certificate to verify your server's identity and so this became known colloquially as an "SSL certificate".
While it isn't often used on the web, in SSL/TLS both parties can present a certificate so that there is mutual authentication.
What you typically have is actually an x.509 certificate. This is the case with the push notification service.
An x.509 certificate contains some information including the identity of the certificate holder, their private key and a signature from a trusted party that can be used to verify the information.
For push notifications, the developer generates a certificate request and submits this to Apple who sign it with their private key. Apple is the trusted party in this case.
When this certificate is subsequently presented to Apple's server they can verify that signature using their public key to confirm the identity of the connecting party.
You have has encrypted the message with their private key (Apple can decrypt it with the public key included in the certificate).
What this means is, that as long as the developer has kept their private key secure (which is why you wouldn't connect directly to the push service from your app, for example) then Apple can be sure of the identity of the server making the connection.
If someone was trying to impersonate your server then, as long as you have kept your private key secure, they can't encrypt the data properly. If they use a forged certificate that uses a public/private key pair known to them then the signature on the certificate won't be valid and Apple will reject it.
I'm supporting one mobile application. Recently I got email that "apns production certificate will expiring soon". After that I checked my backend and found that no any certs using, only auth key. As I know auth keys don't have expiration key. I suppose that apns-cert used on first time after launch or maybe created mistakenly but not using right now. So I have couple of quesions:
1) For well-working APNS, should I have only auth key without APNS certificates? (My idea here - can I safely remove cert without hurting current APNS)?
2) If for example I have non-used in production APNS certificate - I still receive some notifications on my email - like "this certificate will expiring soon"?
Thanks in advance.
1) For well-working APNS, should I have only auth key without APNS
certificates? (My idea here - can I safely remove cert without hurting
current APNS)?
You can safely remove any expired APNS certificate if you are not using. They are not related to the Auth Keys.
2) If for example I have non-used in production APNS certificate - I
still receive some notifications on my email - like "this certificate
will expiring soon"?
Just because you created those certificates, so Apple notifies you of the expiry date whenever they are going to be expired.
You can reference to the following discussion for more details.
https://forums.developer.apple.com/thread/91891
TL;DR version: Is there any way to pass a Server certificate to an iOS client that doesn't involve also passing along the Server's private key?
I have written an iOS client app that communicates with my macOS server app (so I have control over both ends). I have implemented certificate pinning using a self-signed certificate to make things more secure. To accomplish this during development, I hardcoded the Server cert into the iOS client app and told the client to only connect to a server that gives you that exact cert during the TLS handshake. Everything is working great.
However in the real world I am selling this system as a set (1 Server, multiple clients to each customer), so I cannot hardcode a Server cert into the iOS client. My plan is to instead deliver the Server cert out of band (via email) to the iOS client like mentioned here: Making Certificates and Keys Available To Your App:
Apps can only access keychain items in their own keychain access groups.
To use digital identities in your own apps, you will need to write code to import them. This typically means reading in a PKCS#12-formatted blob and then importing the contents of the blob into the app's keychain using the function SecPKCS12Import
One way to provision an identity is via email. When you provision a device, send the associated user an email with their client identity attached as a PKCS#12 file.
My problem is that a .p12 file contains the certificate and the private key of the server - this seems very wrong to pass the private key along as well.
Is there any other way to pass the Server certificate to the iOS client that doesn't involve also passing along the Server's private key?
Thanks!!!
I was overthinking things here, the solution is actually pretty simple.
I just needed to email the Server's public certificate out of band to the client device with a custom extension like cert.myCustomExt1234. This is because the .crt extension is already claimed by iOS so you have to register your app to handle custom extensions (see apple docs here). Then in my app I can do all the logic of cert pinning using that out of band delivered Server public cert.
The key was changing the file extension to something not already claimed by iOS.
In iOS MDM /server url will be called for each operation by the device when it is woken by APNS. I have securely encrypted and signed other profiles at the time of enrollment and successfully passed the server url to device. Its working fine but I have few concerns over this server endpoint as follows.
1) Any client or entity who could send similar plist payload can invoke this service. If a 3rd party has access to a device UDID they can compose this xml payload and invoke this service. From the server point of view it will be hard to track this behavior and identify real devices. To identify that in the real scenario will it send and CMS data or related to validate this scenario?
2) Once the device hit this endpoint from server we can generate operation profiles and send back to devices. For the profiles at the enrollment time we could extract the public certificate from CMS data and encrypt from that. But for this server url how do I achieve that? Seems its not getting any cert like that from device side. Just wondering whether to save the public keys we got in earlier stages but since at the enrollment it goes through 2 SCEP calls not sure what to use it. Will those subsequent profiles payload can be encrypted using previous public cert? Right now I do the signing anyway which works fine.
1.) Any client or entity who could send similar plist payload can invoke this service. If a 3rd party has access to a device UDID they can compose this xml payload and invoke this service. From the server point of view it will be hard to track this behavior and identify real devices. To identify that in the real scenario will it send and CMS data or related to validate this scenario?
Yes, Any client who could possess the UDID and Server URl can send a valid Plist to your server acting like the device.
But they cannot sign the plist with the private key in the device(Which is generated during SCEP enrolment). You would be having corresponding Public key for it to validate the signature.
To force the device to send the signature along each request to Server URL, you have to include SignMessage tag in your MDM payload and set it as true. Like this
<key>SignMessage</key>
<true/>
So when you include this tag along with your MDM payload, you would be get the signature of Identity Private key in the Header HTTP_MDM_SIGNATURE.
Then you can validate the signature using your public key.
2.) Just wondering whether to save the public keys we got in earlier stages but since at the enrollment it goes through 2 SCEP calls not sure what to use it.
Yes I mentioned in the previous answer you should save the public certificate which is issued during SCEP phase. Later you will use that public certificate to Validate the signature from Device and Encrypt the profile you are sending.
Regarding 2 SCEP calls, First SCEP call is to generate the certificate and securely transfer the MDM Payload and actual SCEP payload which will be used as Idenitity certificate for MDM.
So you should use the second one for validating the signature and encryption.
One more hint is, you would have mentioned IdentityCertificateUUID in your MDM payload. The Identity Certificate SCEP payload should have same UUID as its PayloadUUID . That SCEP payload's certificate will be used as the identity certificate for MDM.
Ok. The bottom line that you want to authenticate device.
Each device has an identity cert (a cert distributed in PKCS12 or through SCEP).
Each time when a device communicate to the server it does authentication using SSL client certs.
Most of the time there is a reverse proxy sitting upfront of your web server. It could be Apache or Nginx or anything else. This reverse proxy terminates SSL connection and checks client certificate. Usually, they are configured to pass this client certificate as a header to your web application.
This way your web app can get this header, get a certificate out of it and check against your DB whether a device with specific udid (passed to your endpoint) have a certificate (passed to your webapp in the header).
I am not sure which reverse do you use and whether it's configured properly to pass the certificate.