I hope, some of this information will protect you from making common mistakes during development for iOS9+. You will not find here any detailed instructions. But some topics can stimulate you to go deep within new knowledge.
I’ll also provide a small part of theoretical base of cryptography. For those who are not aware about details – it will be a good point to get new knowledge and to google for new terms. For others – just to refresh.
Theory & History & Good to know
Let’s talk about cryptography base. This science is based on Integer Number Theory, Finite Fields and Probability Theory.
In current context we should also define a term – Negligibility.
In crypto, we consider probabilities that are negligible to be too small to matter. That means if an attack works only with negligible probability, then we consider that attack to be unsuccessful.
Next term we should keep in mind – is PRNG – Pseudorandom number generator or Deterministic Random Bit Generator. The output of PRNG sequence is not truly random. It can be implemented via software algorithms or hardware. Actually the last one can give output much more closer to truly random with higher generation speed.
Negligibility and PRNG – is the foundation of crypto algorithms. And let’s take a look on one old method called OTP (One-time pad).
The main distinct property – is using key with length equal to original text.
It is absolutely impossible to crack it if:
- Key sequence is totally random.
- One key is used only once for concrete message.
- Key length should be equal to message length.
Actually, this method has several implementation problems, thus it is not popular. Two major ones are:
- Key distribution. Sender and Receiver should have this key before starting messaging. Also there are some related problems with authentication.
- Key Length. Huge amount of secured data requires the same amount of key length.
Due to described disadvantages and historical processes two more terms were described to solve it:
- Pseudorandom function (PRF)
- Pseudorandom permutation (PRP)
PRF – we can describe as an abstract black box (with some math functions inside), which takes some input data and returns a random (very close to random) sequence. Every time we send the same message to PRF – it returns the same result. And the main point – there is no efficient algorithm to distinguish real random set and the returned value. By the way Hashes and MACs (Message Authentication Code) are also based on PRF
PRP works in two directions. Having original message and a key – you can get a random sequence output (the same as PRF). But also having this key allows you to restore original text from returned pseudorandom result.
All modern Symmetric Encryption (or Symmetric-Key) systems are based on PRP.
Today there are a lot of successful implementations of PRP, but all of them have one very important problem, that should be solved – key exchange between sender and receiver.
Of course if we have a protected channel with receiver, trusted storage or key was defined and shared before messaging started – it is not a problem. But these cases are not possible in modern networks. We can’t trust anyone.
Now science community should solve the next-following problem:
How can we share keys between sender and receiver using not protected channels?
Most of the solutions today are associated with Ron Rivest, Adi Shamir, Leonard Adleman, well known as RSA public key encryption. But what about key exchange? – Diffi-Hellman key exchange method, in my opinion, was one of the greatest discoveries. I’d like to write more about them, but but I would rather suggest you to watch some videos on Youtube without going deep in math :)
Diffie-Hellman Key Exchange
FYI: If you want to go deeper into cryptography and cryptanalysis – I suggest you take a look on:
- PKCS – Public Key Cryptography Standards
- RFC – Request for Comments
- Padding oracle Attack
- Timing attack
Security Guide overview
Comparing to previous versions of this document – we can see that Apple made a huge improvement in the security area. And of course they can be proud of themselves for implementing best practices.
Secure boot chain
ROM (Read Only Memory) contains the code that will be executed after your turn on your device. It is a totally immutable hardware code that was installed during chip fabrication. If we take a look into Security Guide – they call it “implicitly trusted”. Boot ROM contains Apple Root CA public key, used to verify LLB (Low-Level Bootloader) is signed by Apple. If this check is passed – device will continue loading. It is the first step in the chain of trust. Going thru these steps, we can be sure the next boot level is also signed by Apple.
After LLB operations are finished and verification is passed – the next stage called iBoot starts to run the iOS Kernel (Darwin). iBoot also have its own verification processes related with Apple SSA Server, but we’ll come back to it in few moments. Now, it is interesting to know what will happen if one of the stages (LLB or iBoot) fails? In this case your device will be set to DFU (Device Firmware Upgrade) Mode. Now you can only connect your device via cable to iTunes and restore it.
Let’s come back to the System Software Authorization. The main purpose of SSA – is to be sure that only Apple-signed software can be installed on a device. As any another system – iOS can contain vulnerabilities and updates with fixes that are published quite often. SSA prevents devices to be downgraded to older version, as it was possible before (iOS7).
Another interesting story – how this will work if device is offline? This is the moment when Apple Security Guide is silent. This is the best moment for Jailbreaking science. Of course there is some algorithm based on hash comparison with the previously installed software. Anyway it’s a big topic and if you want to go deeper – I suggest you to read “Hacking and securing iOS Applications” of Jonathan Zdziarski.
Secure Enclave – is a coprocessor for A7 CPU +. For better understanding let’s describe what it has and what it does:
- Has its own encrypted memory
- Build-in hardware PRNG
- Provides all crypto operations for Data Protection key management
- Can communicate with processor using interrupt-driven mailbox pattern (can write a message, but never read it again)
- Can access to the encrypted, shared with processor, memory in Read-only mode
- Responsible for Passcode, Touch ID, Data Protection Classes.
The last topic – is the most interesting one. Secure enclave is responsible for keeping fingerprint and passcode data, processing and validating, and enabling access for user. The interesting fact – processor is forwarding data from sensors to Secure Enclave, but it cannot read it.
From Apple Security Guide
It’s encrypted and authenticated with a session key that is negotiated using the device’s shared key that is provisioned for the Touch ID sensor and the Secure Enclave. The session key exchange uses AES key wrapping with both sides providing a random key that establishes the session key and uses AES-CCM transport encryption
Each device has a high-efficient crypto engine. It is built in between flash storage and memory. It allows to keep data on storage encrypted and load to memory very fast, without serious effect on battery and performance. Chip encryption is based on embedded keys – UID and GID. First one – is unique value for each device, last one – for device family. These keys are not externally accessible.
From Apple Security Guide
The UID allows data to be cryptographically tied to a particular device. For example, the key hierarchy protecting the file system includes the UID, so if the memory chips are physically moved from one device to another, the files are inaccessible. The UID is not related to any other identifier on the device.
Not so long ago (iOS5, iOS6) these keys could be compromised. Patching iBoot loader on device with Jailbreak you can get memory dump from aes_decrypt() function.
One of the first classes for file protection was – NSFileProtectionComplete. The idea was very simple: system allows you to read/write file while device in unlocked. After lock button is pressed – your app has nearly 10 seconds to finish file activities. The protection key is derived from passcode and UID. In case when the passcode is not used – key will be destroyed after device lock.
This implementation made a lot of problems for developers, especially during running long tasks in the background.
So the next solution was NSFileProtectionCompleteUnlessOpen. Using some different crypto implementation allows writing file until it is not closed. Even device was locked.
Previous methods have vulnerability. In case when device was jailbreaked, after rebooting system – files can be compromised. So engineers should find the way to keep data encrypted starting from the boot moment until user will be authorized. Such class solution was called NSFileProtectionCompleteUntilFirstUserAuthentication. In this case files will not be available until user enters Passcode. And, of course, key is not destroyed even after rebooting, as it was in previous class. This method is default for all applications developed for iOS7+.
One more class we can remind – NSFileProtectionNone. The name itself can make you think are not encrypted, but it is not really true. In this case they are encrypted using usual symmetric algorithm and key based on UID. But knowing UID and algorithms that are used – it is not a big deal to restore original data.
Some Default Features overview
- Code Signing. iOS verifies digital signatures for all executable code
- Sandbox. all apps are isolated from each other
- Entitlements. iCloud access, push notifications, Apple Pay, App Sand Box.
- ASLR. Address Space Layout Randomization.
- XN. preventing executing code in memory that was not verified with digital signature. These addresses are specially marked and not executed.
- Extensions. We have to keep in mind any extension has the same access level as the parent application. Excepting keyboards! Internet access is not allowed for them.
This framework is provided by Apple with C interfaces. It contains implementation for:
- All required encryption/decryption, digital signature, hashes algorithms
- KeyChain Services API with wrappers for Swift and Objective C
- Functions for managing certificates
- Secure Transport. Notice, that apple still includes support of SSL 3.0 and TLS 1.0. for compatibility. You have to avoid using them due to the fact they were compromised!
The only advise – be careful with versions that are known as vulnerable (f.e. for heartbleed attack).
Keychain – is a centralized encrypted storage that was designed mostly for storing sensitive data like usernames, passwords, access tokens certificates, with attached public and private keys. The basic engine – is SQLite database. Also keychain can be used for sharing data between applications. Another useful case - is to keep data after the application deletion. Group access to keychain data has become possible after introducing Keychain-Access-Groups. Applications with the same keychain access group entitlement can access items.
Keychain Protection Types
Some of the keychain protection types are similar to file. First one is kSecAttrAccessibleWhenUnlocked. It works in similar way as NSFileProtectionComplete. You cannot have any access to item until you’ll unlock your device. kSecAttrAccessibleAfterFirstUnlock – analog of NSFileProtectionCompleteUntilFirstUserAuthentication. Any access is closed until user will enter passcode after rebooting. kSecAttrAccessibleAlways – I even can’t add anything. Everything is described by a name. I’d like to pay attention on interesting type called kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly. It is used when your app is using iCloud. Also it works only if passcode is enabled. This protection type means that you provide access to items only from current device.
App Transport Security
There are several reasons why Apple strictly enforce developers to design their apps with these new requirements. One of the main important points is that two versions of TLS Protocol (1.0, 1.1) were compromised. Thus now the minimal allowed TLS version is 1.2. Another requirement is related to server certificate. From Apple Develop site
The X.509 digital server certificate must meet at least one of the following trust requirements:
- Issued by a certificate authority (CA) whose root certificate is incorporated into the operating system
- Issued by a trusted root CA and installed by the user or a system administrator
Also using of non-compromised block/stream ciphers, like AES-128, AES-256. For hashed used for MACs (Message Authentication Codes) – SHA2 family.
Requirements for RSA: key length is minimum 2048. In case of using ECDSA for digital signatures – 256 bit. Another very important requirement is:
The negotiated TLS connection cipher suite must support perfect forward secrecy (PFS) through Elliptic Curve Diffie-Hellman Ephemeral (ECDHE) key exchange
If you want to learn more about requirements – welcome on page https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35
- Never use a password or hash as an encryption key
- Do not keep keys in your app, even in RAM
- Use PBKDF2 function with a lot of iterations
- Add your own encryption logic and salt
- Do not send unencrypted or weakly encrypted passwords anywhere
- Avoid keeping tokens. Configure them to minimal live time as possible
- Notify user when he or someone else were using his credentials to log in. In both successful and unsuccessful ways
- To block debugging your app - use ptrace() in you code
- Clear your pasteboard when app goes to background mode
- Turn off spelling check in all fields where sensitive data can be placed
- Enforce users to create complex passwords
- Implement MFA (Multi Factor Authentication)
All described is a drop in the bucket, but I hope you have found some useful topics in this article. And going deep into any of them will help you to create amazing things.