How to generate a certificate signature on the iPhone? - ios

If I had a private certificate file and a string on the iPhone, how do I use them to generate a signed string that can be verified by a server with the matching public key? What library should I use on the iPhone?

I would take a look at Certificate, Key, and Trust Services Reference on Apple's website. You can import the PKCS #12–formatted blob with SecPKCS12Import and sign the data with SecKeyRawSign.

Related

What is the file with .p8 extension? (APNs Auth Key / JWT)

I think it is a little ridiculous but it's hard to find information about what is this file. I've found a lot info how to get this Apple Push Notification Authentication Key, but i also want to know exactly what is it.
Here is some info i have found:
Benefits:
No need to re-generate the push certificate every year;
One auth key
can be used for all your apps;
Same for sandbox and Production.
From Apple Docs:
Token-based provider connection trust: A provider using the
HTTP/2-based API can use JSON web tokens (JWT) to provide validation
credentials for connection with APNs. In this scheme, you provision a
public key to be retained by Apple, and a private key which you retain
and protect. Your providers then use your private key to generate and
sign JWT provider authentication tokens. Each of your push
notification requests must include a provider authentication token.
You can use a single, token-based connection between a provider and
APNs can to send push notification requests to all the apps whose
bundle IDs are listed in your online developer account.
Every push notification request results in an HTTP/2 response from
APNs, returning details on success or failure to your provider.
Further check Token-Based Provider-to-APNs Trust section.
Questions:
What is actually the .p8 file?
What programm can open it? (Keychain didn't work for me)
Is there a way to convert it to .pem or .p12?
A little flow-out question in order to not create a new topic: Does the server side operate with .p8 the same way as .p12 or it should be additional tools added?
The following is the state of my research:
The APNS .p8 file contains the PRIVATE KEY that is used to SIGN the JWT content for APNS messages.
The file itself is a pure text file, the KEY inside is formatted in PEM format.
The part between the -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- is a base64 formatted ASN.1 PKCS#8 representation of the key itself. Some can use the following web service to extract its contents (ASN1JS).
The KEY itself is 32 bytes long and is used to create the required ECDSA P-256 SHA-256 signature for the JWT. The resulting JWT looks like this '{JWT header base64 encoded}.{JWT payload base64 encoded}.Signature (64 bytes) base64 encoded'.
There are a lot of web services to decode such tokens, but some couldn't check the signature, as the corresponding PUBLIC KEY isn't known (Apple keeps it secret when providing the PRIVATE KEY).
EDIT: It seems, that the PUBLIC KEY is also included in the .p8 file, it can be extracted via OpenSSL (and is visible when decoding the ASN.1 content: the 520 bit stream).
openssl ec -in AuthKey_123ABC4567.p8 -pubout -out
AuthKey_123ABC4567_Public.p8
File extensions are just a convention, but most likely the .p8 extension is used to indicate that it is a PKCS#8 PrivateKeyInfo (or EncryptedPrivateKeyInfo).
I'd expect the Keychain program to be able to open it as "a key", but not having a mac at hand I can't say. It should open with SecItemImport (kSecFormatOpenSSL, kSecItemTypePrivateKey).
Is there a way to convert it to .pem or .p12?
Assuming you mean "certificate" by .pem, no. If you mean PEM encoded, sure. It's either "BEGIN PRIVATE KEY" or "BEGIN ENCRYPTED PRIVATE KEY", depending.
It can also, technically, be converted into a PKCS#12. But Apple's PKCS#12 importer won't import (last I saw) private keys that it can't figure out what certificate they belong with (from the same PKCS#12).
This is just a private key, there's no certificate (thus no expiration). So certificate-based approaches don't make sense.
Does the server side can operate with .p8 the same way as .p12 or it should be additional tools added?
This depends entirely on the details of the protocol, which I don't know. If the protocol transported the certificate then different machinery is involved with the conversion. If it just transported a signature and the server looked up the public key for verification then nothing changed server side.
It's a text file! The .p8 extension signifies a simple text file containing public/private key. You can open it with any text editor (TextEdit, vim, Sublime Text) to see your key.

What is Apple's certificate?

I'm trying to understand what the certificate is. I'm talking about the .cer file.
In the description it sounds like it is a public key but if it is, than why do I need Certificate Signing Request (CSR) when creating it?
Everywhere I can find "what is a developer certificate for" and so on, but there is no information what the certificate — as an entity — is.
So my questions are:
What is .cer file? (Not .p12)
What is the difference between certificate and public key?
1) The .cer is an commonly used extension for certificates.
Certficates are digitaly signed and encoded documents. To my understanding certificates are documents which contain data (strings etc.) and are encoded. Simply put it is a container for sensitive data.
For details read: DER vs CRT vs CRM vs PEM
2) The public key simply put is a value (String for example). This value is stored in a certificate .cer file.
For better understanding this video might help: Private and public key
The difference is that a certificate can contain a public key but a public key cannot contain a certificate.
A certificate certify who you are, its a kind of identity card or passport or whatever. A public key is something used to secure something, somehow like a real key closes a safety box not to let everyone have look inside.
Then you may have the need to certify that a public key is the one it claims. A certificate is (normally) obtained from another trusted authority (like your passport is delivered by a legal entity). If not how would you trust a public key I'll give to you? It can be a hacked public key, but if you have a certificate that belongs to it, then (if you trust the authority) you'll know it's really mine and not a forged one.
You may read Public Key Certificate on Wikipedia for example.
.cer files are certificates in some well defined format.

Is it possible to create a self signed certificate in iOS?

Is it possible to create a self signed certificate in iOS ? And is it possible to extract the public key from public key certificate created on server and store in Keychain?
You need to use the Apple documented process to generate your certificate.
Extracting keys from the keychain is ok.

verify the digitally signed data with public key using RSA in iOS

How to verify the digitally signed data with public key using RSA during decryption at device end. I don't want to use openssl.
Hoping for answer.
Try looking up using PGP. You can use RSA. Here is a link to read more about it if you did not know already. http://www.gnupg.org

Is it possible to generate certificate signing request(.csr) using security framework in iOS?

I would like to make HTTPS request with a server require client-certificate authentication. I looked into this Creating a SecCertificateRef for NSURLConnection Authentication Challenge. It worked as expected.
However, it needs to prepare the p12 file which includes the private key. It would be secured as it needs a password to import the p12 file using SecPKCS12Import().
However, there could be other option. That is the iOS-client should make a certificate signing request(.CSR) and let a third party (the server) sign it.
For my search, I see that I can use SecKeyGeneratePair() for generating a key pair. But I don't see any API that generate a CSR.
Do I really need OpenSSL to achieve this?
Also, a bit off topic, once the iOS-client somehow receives the signed certificate. I can use SecCertificateCreateWithData() to retrieve an SecCertificateRef(). However, to fill in a NSURLCredential. I also need the SecIdentityRef which come from p12 file using SecPKCS12Import(). How can I retrieve a SecIdentityRef without SecPKCS12Import() but just a certificate file like crt or der?
There is no explicit support for CSR in Security Framework in iOS. However, it is not that difficult to build CSR 'manually' - it is just ASN.1 DER block of data that are available at iOS runtime.
Here is pseudo code of that:
Use SecKeyGeneratePair() from Security Framework to create fresh public/private key
Implement getPublicKeyBits method to retrieve NSData-form of fresh public key (see https://developer.apple.com/library/ios/samplecode/CryptoExercise/Introduction/Intro.html )
Implement getPrivateKey method to retrieve SecKeyRef from Keychain
Follow http://www.ietf.org/rfc/rfc2986.txt to construct ASN.1 DER of CSR in NSMutableData
Use CC_SHA1_* to create signature hash of Certification Request Info (part of CSR)
Use SecKeyRawSign and private key to sign CSR
This will create proper CSR (in form of NSData) that can be sent to CA for approval.
My implementation is available on GitHub: http://github.com/ateska/ios-csr .
To anyone who comes across this in the future, I encountered outfoxx's Shield library which makes it super easy to create CSRs via Swift.

Resources