# iMessage Privacy

iMessage is probably one of the most trendy instant messaging systems. Apple presents it as very secure, with high cryptographic standards, including end-to-end encryption preventing even Apple from reading the messages. Is this true?

## Presentation

Here you can download our slides of the presentation we gave at HITBSecConf2013:

http://blog.quarkslab.com/static/resources/2013-10-17_imessage-privacy/slides/iMessage_privacy.pdf

• What we are saying: Apple can read your iMessages if they choose to, or if they are required to do so by a government order.

As Apple claims, there is end-to-end encryption. The weakness is in the key infrastructure as it is controlled by Apple: they can change a key anytime they want, thus read the content of our iMessages.

Also remember that the content of the message is one thing, but the metadata are also sensitive. And there, you rely on Apple to carry your messages, thus they have your metadata.

Now, you can read the article or jump to end of the article where we summarized it.

## 1. Instant messaging eavesdropping

For years now, every time a new instant messaging service has risen, lot of people ask questions about its security. Remember BlackBerry or Skype at the beginning, they claimed to be encrypted thus secure, impossible to eavesdrop. Years later, answers are coming from everywhere to deny that [1] [2]. For people working in the security industry, this is not a surprise. It is the role of a government to ensure security of people, and governments need ways to eavesdrop dangerous people. The question is more ethic than legal, and deals with the power given to intelligence agencies.

Recently, Snowden's leaks showed it was even worst than what many people imagined: crypto standard backdoored, collusion with major companies, massive data collection, intrusion everywhere, ... Despite that context and the legitimacy for government to practice lawful interception, all companies involved tried to minimize their role, and used a simple excuse: we just followed the law. However, one company has claimed it was impossible for them to eavesdrop their own instant messaging, and thus they are unable to collaborate with US government, even if requested to do so.

After Snowden's leaks, Apple published a statement, called Apple’s Commitment to Customer Privacy. As questions were around for some time on iMessage, Siri or Facetime, they clearly answered [3]:

There are certain categories of information which we do not provide to law enforcement or any other group because we choose not to retain it. For example, conversations which take place over iMessage and FaceTime are protected by end-to-end encryption so no one but the sender and receiver can see or read them.Apple cannot decrypt that data.

According to that statement, Apple can provide some metadata (who sends a message to who, the date, ...) but the content of a conversation would be excluded. We will show in this article it is not true. Apple can get access to encrypted message, despite end-to-end encryption. Does it mean they do it? Only Apple and some 3 letters agencies can answer, we can not.

Now, let's go into the details of our analysis.

## 2. Lack of certificate pinning: so what?

First thing first, we notice than pretty much all the traffic is encrypted. Good point. All communications to Apple's servers are made through a secure SSL tunnel. We do not need to know what protocol is used or how packets are forged. The first thing we want to try when we see that is adding a certificate to perform a MITM. We were actually very surprised it worked as easily, which means there is no certificate pinning. We created a fake CA, and added it to the iPhone keychain. Then, we could proxify communications much more easily. When a SSL communication arrives to the proxy, we generate a certificate signed by the newly added CA, and everything becomes unencrypted.

Second surprise was actually bigger: we saw our AppleID and password going through this SSL communication. Yes, the clear text password... There can be a lot of good reason to send the password as cleartext, ssh does it for instance. But here, we dont see any reason for Apple to get our password.

Firstly, it means that Apple can replay our password using for instance our email also on many websites. Ok, Apple has no reason to do so. But what of intelligence agencies? Secondly, it also means that anyone capable of adding a certificate and able to proxify the communications can get user's AppleID and password, thus get access to iCloud accounts, backups, buy apps, ....

Here is an example of what we get:

POST /WebObjects/VCProfileService.woa/wa/authenticateUser
'content-length': 223,
'accept-language': en-us,
'accept-encoding': gzip,
'content-encoding': gzip,
'host': service.ess.apple.com,
'accept': */*,
'user-agent': com.apple.invitation-registration [Mac OS X,10.8.3,12D78,Macmini4,1],
'connection': keep-alive,
'x-protocol-version': 7,
'content-type': application/x-apple-plist,
'x-ds-client-id': t:3A5DC02C47249FC50EF0FF1B8CF3073C9EBD0668


And here are content of posted data:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<string>Icandoaproperkeynote</string>
<string>tim_c@icloud.com</string>
</dict>
</plist>


We tried to play with the certificates for a while. We came up with iPhone Configuration Utility. This software is Apple's solution for enterprise to manage their iPhone. When this software is used for the 1st time and a device is plugged, a CA is added to the device. MDM administrators can do this transparently to enrolled devices

The consequence is that in a company where iPhones are managed by IT, they want to setup a proxy and invisibly proxify communications from / to the iPhone, thus gain access to very personal information. Note the certificate pinning is not performed at any layer, PUSH or iMessage, so various problems can happen here and there.

## 3. The protocols: the client, PUSH & ESS servers

In this part, we will describe the usual process, with all the protocols and cryptographic steps involved.

### 3.1 The client on the device

Each device has its own certificate, which is 1024 RSA with a CN=<Push GUID> (obviously, GUID has to be replaced with device's GUID). The client is MobileSMS / Message.app, but this application also relies on other services. The 2 mains are:

• apsd: the Apple PUSH server daemon, in charge of carrying the messages from Apple to the devices.
• imagent: the background process for iMessage tasks, like keeping connection when app is closed, etc.

When a message is sent to someone, Apple is in charge of transporting the message. It means 2 things:

• Given a destination address (an URi, it can be a phone number or an email for instance), Apple has a way to link it with all devices related to that URI (iPhones, iPads or OS X systems).
• Once Apple knows all the devices involved, Apple brings the message to the proper devices.

### 3.2 The PUSH protocol

PUSH protocol [4] has been designed as a remote notification protocol over networks. It is used for iMessage of course, but also for FaceTime, GameCenter or by send party application when they want to notify of an event. Think about Facebook, Whatsapp or any news application notifying you than something just happened. Each time, it is based on the very same protocol, PUSH.

Here is how Apple defines it:

Local and push notifications are great for keeping users informed with timely and relevant content, whether your app is running in the background or inactive. Notifications can display a message, play a distinctive sound, or update a badge on your app icon.

PUSH behaves as a transport protocol, in charge of delivering a payload, whatever it is, to set of devices. Hence, iMessage itself is a payload in regard of the transport protocol.

All PUSH communications are made in TLS to server port 5223 when it comes to iMessage:

• Hostnames are taken from [0, ..., 255]-courier.push.apple.com
• The client certificate, specific to a device, which is explained right after.

#### The client certificate

The PUSH certificate is generated when the device is registered and activated at Apple. During the 1st connection to Apple's server, a certificate request is sent to albert.apple.com. This server runs a certificate authority, called Apple Iphone Device CA, in charge of signing every request.

This certificate is very sensitive as it is the one in charge of ALL PUSH communications from the device: PUSH communications are secured with it, with both client and server authentication.

As such, this certificate is not directly involved in iMessage, but since iMessage is carried over PUSH, it has a role to play anyway.

#### The Push-Token

From the PUSH layer, how it works is kind of magic known only by Apple. From client side, here is what we see. First, we write a message, and press the send button. Doing so, the client requests from Apple's ESS servers the information needed to send the message. The ESS Server sends back 3 pieces of information:

• A Push-Token, which is a unique identifier for a pair iDevice.
• Two cryptographic keys we will describe right after.

The Push-Token is computed by Apple when a device registers to the service. The generation of the Push-Token is defined as opaque by Apple since it is made server side, same goes for its precise usage. For now, we see it as the registration of a provider and a routing information.

As a provider because one needs to register itself as a iMessage provider, but also as a routing information because Apple needs to know where to deliver the messages. As a matter of fact, Apple fanatics users often have more than one device, and a iMessage must be delivered to all the devices at once.

So, when the client sends one message, it actually sends as many messages as the recipients has Push-Tokens, so that the message can be delivered to each iDevice. These messages are sent to the Apple Push Network Service (APNS) through a gateway on port 5223 as explained earlier.

For instance, on a OS X system, one can see:

root@joker:~>> ps aux |grep apsd
root 90 0.0 0.1 2467868 8052 ?? Ss Thu09AM 0:06.06 /System/Library/PrivateFrameworks/ApplePushService.framework/apsd
root 20295 0.0 0.0 2432768 588 s003 S+ 3:08PM 0:00.00 grep apsd

root@joker:~>> lsof -p 90 |grep TCP
apsd 90 root 9u IPv4 0x667b30bc14a94f93 0t0 TCP joker.lan:65158->17.172.232.179:5223 (ESTABLISHED)

root@joker:~>> whois 17.172.232.179
NetRange:       17.0.0.0 - 17.255.255.255
CIDR:           17.0.0.0/8
OriginAS:
NetName:        APPLE-WWNET
NetHandle:      NET-17-0-0-0-1
Parent:
NetType:        Direct Assignment
RegDate:        1990-04-16
Updated:        2012-04-02
Ref:            http://whois.arin.net/rest/net/NET-17-0-0-0-1
OrgName:        Apple Inc.
OrgId:          APPLEC-1-Z
Address:        20400 Stevens Creek Blvd., City Center Bldg 3
City:           Cupertino
StateProv:      CA
PostalCode:     95014
Country:        US
RegDate:        2009-12-14
Updated:        2011-03-08
Ref:            http://whois.arin.net/rest/org/APPLEC-1-Z
...


When the APNS servers receive that, PUSH magic comes into play. That is not described in the documentation, but we can assume, reading from [5] that Apple relies on a connection between the APNS and the devices. Based on the Push-Token for each message, Apple is able to select to what device a PUSH notification must be sent to.

#### MITM at the PUSH layer

What about attacking that PUSH layer? Attacking it means being in between the client and Apple' servers in order to read the messages. But since the communication relies on TLS, some efforts are needed to provide certificates.

There is a very convenient tool for that: PushProxy [6]. It provides a simple API to mess with both received and sent messages. Since a lot a prerequisites are needed to perform that on a real communication, we will work locally on the device itself for now.

First, we need to add a root CA to the system's keychain, so that proxy's certificates are trusted. That way, the real client will trust the messages from the proxy. This is easy, but we also need to communicate with Apple. And as we said, the authentication is mutual, so we need either to inject a new certificate to albert.apple.com, or to use an already signed certificate.

We pick the 2nd option: we extract the private part of the device's PUSH certificate and give it to the proxy. Last but not least, we need to redirect all connections to the proxy, which we did by modifying the /etc/hosts file of the device.

We are now ready to see what is in the PUSH messages. So, the PUSH layer of an iMessage payload looks like that (XX bytes are not set as they depends on the content of the message):

0a                    >> Message Type
XX XX XX XX           >> Next Length
04 00 04 XX XX XX XX  >> Identifier (4 bytes)
01 00 14 XX .. .. XX  >> Topic Hash (20 bytes)
02 00 20 XX .. .. XX  >> Push-Token (32 bytes)
03 XX XX ...          >> iMessage payload


Before going into iMessage payload, we need to give a brief explanation on iMessage IDs.

### 3.3 The iMessage IDs

From now on, we will refer to iMessage simply as IM. There are a lot of information involved at the IM layer:

• AppleID: as already explained, that is the very heart of an account for Apple.
• URI: same format as an AppleID, which is either an email address or a phone number. One AppleID can have several URI. When it is an email, it is verified with a link to click. When it is a phone number, they are authorized only from the SIM card.
• Push-Token: as explained earlier, it is used for iMessage to identify a device on which an URI is registered. As such, a Push-Token is unique for each URI used on a device.

### 3.4 Sending an iMessage

When a user wants to send an iMessage, he firstly provide one or several destination URI. Since the communication is end-to-end encrypted, it means either the devices directly exchange the needed keys, or there is a key directory involved somewhere.

There is actually such a directory, called ESS servers (dont ask us what ESS stands for, ask Apple). So, to retrieve the keys, the iDevice sends the following request to the server:

GET /WebObjects/QueryService.woa/wa/query?uri=tel:+33123456789
'Host': service1.ess.apple.com
'Content-Type': application/x-apple-plist
'x-id-cert': [Provision Certificate]
'x-id-nonce': [Random Nonce with Timestamp]
'x-id-sig': [Query Signed with Provision Cert.]


In this example, the iDevice wants to retrieve the keys for URI "+33123456789".

It is important to notice this request is signed with yet another certificate, called Provision. This certificate is generated client-side, and signed by the authority called Apple IDS DS-ID Realm CA during iMessage authentication. It is valid for one month.

{
'push-token': [PushToken]
'client-data':
{
'show-peer-errors': True,
'public-message-identity-version': 1.0,
'public-message-identity-key': [Public Keys Buffer]
}
}


It is actually a XML plist. We converted it to JSON to make it more readable. In our example, there is only one identity returned. However, if the destination URI have several devices and registered accounts under his AppleID, the same information would be given for each of them.

The answer contains the Push-Token, well-known now. But it also carries a buffer full of public keys:

• One ECDSA (256-bit) used to verify the signature of messages sent by the destination URI on this device. That way, when the destination URI replies, we'll already have the ECDSA key to check the signature.
• One RSA (1280-bit) used to encrypt iMessage sent to the destination URI.

With both these keys, we can setup a secured (?) communication with the destination URI, and all the related devices.

We finish our explanation of the PUSH protocol by providing an iMessage payload. Now, we will see what this payload is made of.

This payload is in an Apple specific format, called bplist (binary-plist). It is designed to embed serialized data as dictionary. Several kinds of data are defined, including the usual ones: NSString, NSNumber, NSDate, NSArray, NSData and NSDictionnary, and so on.

Here is an example of such a bplist:

D:   True
E:   'pair'
P:   <variable length binary data> (iMessage payload, deflate compressed)
U:   <128bit binary data> (iMessage UID)
c:   100
i:   <32bit integer> (messageId, same as in PUSH header)
sP:  mailto:tim_c@icloud.com  (sender URI)
t:   <256bit binary data> (sender Push-Token)
ua:  [Mac OS X,10.8.5,12F37,MacBookPro10,2] (sender OS and hardware version)
v:   1


The ua field is totally useless but is sent on every request, for Apple statistics?

Anyway, the P field is the IM payload. It is encrypted then compressed (yes, yes, encrypted first, compressed after). It is composed with the following keys:

(byte)     0x02          version?
(short)    ciphertext    length
(data)     ciphertext    RSA / AES-CTR data : ciphered with the RSA public key of the recipient
(byte)     signature     length
(data)     signature     ECDSA signature of <ciphertext> : computed with the ECDSA private key of the emitter


In cleartext, the data is also a bplist, which we called inner bplist:

p: array of URIs in the discussion group
t: iMessage text (for iOS)
v: version (1)
x: iMessage html (attachments, and style - for OS X)


Let's spend some lines on the RSA / AES-CTR data. This data is the actual message sent to the target (the URIs, the message itself, attachment if any). Let us describe how it is built:

1. Let's call ibplist the cleartext data.
2. A 16 random byte are generated to be the AES key.
3. The data is encrypted with AES in CTR mode, giving AES(ibplist)
4. The 128-bit key is put at the beginning of the output buffer

5. The 128-bit key and 808-bit of AES encrypted data are ciphered with RSA-1280 using a public exponent of 65537 and PKCS1 OAEP padding. It gives a 1280-bit buffer.

1. That buffer is then signed with the owner's ECDSA key.

The RSA key used here is the one retrieved from ESS server, as mentioned above.

#### Sending attachment with iMessage

As most instant messaging service, iMessage allows to send attachment. Most of the time, people are sending picture from their iPhone. But any kind of file can actually be used.

When an attachment is sent, it is actually stored on iCloud servers, on a dedicated repository. The attachment is encrypted with AES, and the key is sent to the destination as payload in the iMessage, altogether with the link to the file. Since this is encrypted with the destination RSA key, this is as safe as the RSA key itself.

All this is performed with the <FILE> in the HTML message:

<file
name="<name>"
width="<width>"
height="<height>"
datasize="<size>"
mime-type="<mime type>"
uti-type="<uti type>"
mmcs-owner="<identifier>"
mmcs-url="<URL>"
mmcs-signature-hex="<signature>"
file-size="<size>"
decryption-key="<key>"
/>


Note that it seems to be OS X specific.

#### Easter eggs or tricks

• Adding a subject: there is an option to add a subject to the iMessage in the configuration panel. This is triggered with the s key and a text to the inner plist.
• For IRC geeks, /me is working ... only on OS X. Send a message starting with "/me" and it will be displayed differently on OS X and iOS.
• The existence of a URI is not verified in the discussion group, which means you can add fake URI. Of course, a real URI has to be in the list but you can then make believe to the destination you actually send an iMessage to Tom Cook for instance.

## 4. MITM attacks

iMessage is complex because it relies on PUSH and a lot of crypto is involved at all layers. In this section, we will study what are the conditions to perform a MITM attack on iMessage, now that we hopefully made the protocol less opaque.

In order to do that, we will set an attacker in various positions: between the sender and Apple, between Apple and the receiver. If you want a quick and dirty overview, you might want to have a look at our original paperwork describing the MITM.

### 4.1 Test protocol

As we have seen, the 2 main services for iMessage are the PUSH servers and the ESS ones. So, in order to perform any attack, we need to impersonate these servers. There are lots of ways to do that, from ARP spoofing to injecting BGP routes (if you can), but we simply keep playing with /etc/hosts, as for the PUSH proxy earlier.

Here are the tools we used:

• Python to be able to run following tools
• PushProxy with Quarkslab’s imessage-mitm.py handler to intercept iMessages
• Quarkslab’s ess-mitm.py to intercept and modify Apple ESS responses
• A DNS proxy software. We used dnschef.

From the crypto point of view, we added a root CA to the target keychain so that we are able to serve our own certificates with no complaint from the iDevice.

From there, we have all our tools running locally, we are ready.

### 4.2 One-sided MITM

Here, the attacker is between the sender and Apple's server, on sender's iDevice. Let's call the sender Dhillon, and the receiver Belinda. We will explain step by step how it is going on. An evil guy called Evil, is in the middle.

1. Dhillon writes a message to Belinda.
2. Dhillon's iDevice makes a request to ess.apple.com
3. Evil intercepts that request:
1. Evil requests from ess.apple.com Belinda's information (Push-Token, RSA and ECDSA keys)
2. Evil replaces Bel's RSA and ECDSA keys with his own
1. Dhillon sends his message to Belinda: it is encrypted with assumed Bel's RSA (Evil's actually) key, signed with Dhillon's ECDSA key.
2. Evil intercepts the IM payload:
1. He can decrypt it with his own key
2. He can alter it and recipher it with Belinda's real RSA key
3. Since he is on the device, he can use Dhillon's ECDSA private key to re-sign the message.
1. Belinda gets the message, it is properly signed and she can read it.

As everyone can notice, a very strong requirement here is that the attacker, Evil, gets access to sender's ECDSA private key.

Let's see now what is happening when Belinda is answering to the message:

1. Belinda writes a message.It is ciphered with Dhillon's RSA key, and signed with Belinda ECDSA key.
2. The message is sent to Apple Push servers, then to Dhillon's mobile
3. Evil intercepts that message:
1. Evil can decrypt the message as he has access to Dhillon's RSA private key.
2. Evil can change the message, and recipher with with Dhillon's RSA public key.
3. Evil signs the modified message with his own ECDSA key as Dhillon's believe it is Bel's (see step 3.2 in the previous description).
1. Dhillon receives the forged message:
1. He checks the signature with Evil's ECDSA key (believing it is Bel's): everything is fine.
2. He decipher the message with his own private RSA key.

Once again, in reception, there is a strong requirement: the attacker, Evil, needs to get access to the RSA private key.

### 4.3 Two-sided MITM

Now, we are thinking big: we want to perform a MITM on Dhillon and Belinda at the same time. So, we assume now that Evil is running his MITM on both Dhillon's and Belinda's iDevice.

As example, Dhillon is sending a message to Belinda:

1. Dhillon writes a message to Belinda.
2. Dhillon's iDevice makes a request to ess.apple.com
3. Evil intercepts that request:
1. Evil requests from ess.apple.com Belinda's information (Push-Token, RSA and ECDSA keys)
2. Evil replaces Bel's RSA and ECDSA keys with his own.
1. Dhillon sends his message to Belinda: it is encrypted with assumed Bel's RSA (Evil's actually) key, signed with Dhillon's ECDSA key.
2. Evil intercepts the IM payload:
1. He can decrypt it with his own key
2. He can alter it and recipher it with his own key.
3. He signs with his own key too.
1. The message is sent to APSN and delivered to Belinda's device.

Since Evil is now on both side, things are symmetric here, so let's go:

1. Evil receives the message on Bel's iDevice.
2. Evil deciphers the payload with his own RSA private key.
3. Evil encrypts the message with Bel's RSA public key.
4. Evil signs the encrypted message with his own ECDSA key, since he provided this key to Belinda presenting it as Dhillon's.
5. Evil delivers the message to Belinda
6. Belinda checks the signature, which is ok and appears to be from Dhillon (since it has been signed with Evil's key, which is Dhillon's ECDSA alleged key).
7. Belinda deciphers the message.

The main requirement here is for Evil to be, at the same time, in between Dhillon and Apple on on end, and Belinda and Apple at the other end. Still a strong requirement for most attackers, but we didn't need users' private keys anymore!

### 4.4 MITM by replacing Apple

Let us perform an excise assuming an attacker is able to replace Apple to perform the MITM. This assume huge requirements:

• Huge network control to redirect the traffic of the iDevice (through DNS or whatever).
• Verified PUSH and ESS certificates, for each target.

Clearly, not the many people have such capabilities. Maybe 3 letters agencies... Who knows.

How would it work? Like a classical MITM:

1. Evil gives his RSA and ECDSA to Dhillon
2. Evil gives his RSA and ECDSA to Belinda
3. When Dhillon sends a message, Evil can read it, change it and resign it before passing it to Belinda
4. When Belinda receives it, she deciphers the message with her RSA key, and check the signature with Evil's ECDSA key, even through she believes it is Dhillon's.

Since, Evil is really in the middle, things are the same when Belinda answers to Dhillon:

So, what are the requirements here:

1. For that to work, he needs a valid CA in the devices of the targets.
2. The attacker needs to redirect the traffic from both targets to himself.
3. He needs to provide keys to each target impersonating the other end of the communication.

Obviously, this attack is not realistic for the average attacker.

### 4.5 MITM being Apple, or why end-to-end encryption is not enough

Actually, not all attackers can fulfill the above requirements. But now, let's have a look at Apple's position there:

1. For that to work, he needs a valid CA in the devices of the targets.

> Apple has such a certificate.

2. The attacker needs to redirect the traffic from both targets to himself.

> Apple does not need to do that since all traffic is going anyway through the PUSH server.

3. He needs to provide keys to each target impersonating the other end of the communication.

> Apple owns the key server, ESS.

So, definitely, Apple can perform the MITM, they just have to tamper with the keys the send to the targets. Then, you remember how iMessages are encrypted: a RSA key encrypts an AES key.

Since Apple can change the keys, Apple can then decrypt the AES key, and as a consequence, the content of the message.

Remember Apple's statement:

For example, conversations which take place over iMessage and FaceTime are protected by end-to-end encryption so no one but the sender and receiver can see or read them.Apple cannot decrypt that data.

So, yes, there is end-to-end encryption as Apple claims, but the key infrastructure is not trustworthy, so Apple can decrypt your data, if they want, or more probably if they are ordered to.

## 5. Preventing MITM from Apple or others

There are actually not that many solutions. The main problem here comes from Apple as they control the key infrastructure. So, the 2 solutions are:

1. Make the key infrastructure less opaque and more public
2. Encrypt message with key not controlled by Apple.

These 2 solutions are under active development. Stay tuned for more information.

### 5.1 iMITMProtect

We have developed a simple Mac OS X application, iMITMProtect which hooks some functions involved on iMessage. The application is very simple / stupid:

• When Push-Tokens and keys are received, they are stored in a local database.
• Each time a token or a key is received, we look up for the corresponding URI in the database, and check it is the same or not. If not, Houston, we have a problem.

As soon as a jailbreak will be available, we will port it as a Cydia package.

### 5.2 iMessage over-encryption

If one considers iMessage as an insecure channel, the solution is to encrypt the data sent to that channel. Setting up such an encryption is not easy, even without considering the General Conditions of Use.

We cant say more on that now, except it is tricky!

## 6. Last words

Apple's claim that they cant read end-to-end encrypted iMessage is definitely not true. As everyone suspected: yes they can!

Suspecting is not knowing, and we hope to have dig enough in the protocol to show how Apple could do it.

But shall we continue to use iMessage? MITM attacks on iMessage are unpractical to the average hacker, and the privacy of iMessage is good enough for the average user.

If the informations being exchanged are sensitive to the point that you don’t want any government agencies to look into them, don’t.

Apple, make a more transparent PKI and document the protocol, and it could be considered the most practical and secure real-time messaging system available.

Yes.

You should skip this part if you dont want to spoil the details. If you are in a hurry and just want the answers, this part is for you. We have analyzed iMessage, Apple's instant messaging service, wondering: how to eavesdrop iMessage.

Here are the facts:

• Involved cryptography is based on well-known algorithms (AES, RSA, ECDSA) with proper key sizes and implementation.
• Code in charge of key generation is open source.
• No certificate pinning is performed between client and PUSH servers (Apple's servers involved in iMessage).
• Authentication between client and Apple's servers is protected with strong obfuscation and whitebox cryptography, preventing the development of 3rd party iMessage clients.
• User password is sent clear-text through a secure SSL channel to Apple. This is clearly an issue for people using the same password at several places (mail, bank, whatever) as Apple knows this password.
• No pinning + cleartext password means that if somebody manages to add a certificate in a device, he can perform a MITM, thus get the user's AppleID and password. That is the key to everything belonging to the user.
• Bonus: if the device is connected to iPhone Configuration Utility, Apple's enterprise solution for management of iPhones, a trusted CA is added. Consequence is that all subsequent certificates signed by that CA will be trusted to create the SSL communication. It means all companies using that are able to retrieve their employee's AppleID and password by simply proxifying the SSL communication.
• iMessage is carried over Push protocol, the very same protocol used but FaceTime, GameCenter or notification services.
• PUSH is tunneled inside SSL to Apple's PUSH servers on port 5223.
• Every Apple device is identified by a unique Push-Token.
• When someone sends one message, the client looks for all Push-Tokens related to that destination (called an URI) to transport the message to every device where the URI is registered.
• When one sends an iMessage, the client firstly connects to an Apple key server, called ESS, to get the target public keys.
• The clients retrieves 2 keys:
• One ECDSA (256-bit) used to verify the signature of messages sent by the destination URI on this device. That way, when the destination URI replies, we'll already have the ECDSA key to check the signature.
• One RSA (1280-bit) used to encrypt iMessage sent to the destination URI.
• The iMessage payload is actually a binary plist, designed to embed serialized data as dictionary.
• The iMessage payload is encrypted with a random AES key, the key is appended at the beginning of the encrypted payload, the 1280 first bits are encrypted with destination RSA key.
• Every message is signed with sender ECDSA key.
• iMessage can be used to send attachment. They are stored on iCloud, encrypted with an AES session key as explained above.
• Since Apple controls ESS servers, and all iMessages are routed to Apple's PUSH servers, Apple is able to perform MITM:
• Apple sends fake public RSA / ECDSA key to the sender
• Apple can then decipher, alter the payload of the message and sign it before sending to its final destination.
• So, yes, there is end-to-end encryption as Apple claims, but the weakness is in the key infrastructure as it is controlled by Apple: they can change a key anytime they want, thus read the content of our iMessages.