Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2011-208
$eventId
ID of event: wwdc2011
$eventContentId
ID of session without event part: 208
$eventShortId
Shortened ID of event: wwdc11
$year
Year of session: 2011
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2011] [Session 208] Securing Ap...

WWDC11 • Session 208

Securing Application Data

Core OS • iOS • 54:01

Securing data is an important feature of any application. Learn how to use the Keychain and get recipes to protect application data. Understand how to determine data caching policies, what to do when a device locks, and how to handle upgrades and restores of iOS devices.

Speakers: Michael Brouwer, Conrad Sauerwald, Andrew Whalley

Unlisted on Apple Developer site

Downloads from Apple

HD Video (246 MB)

Transcript

This transcript was generated using Whisper, it may have transcription errors.

Good morning, everybody. Thanks for coming. I'm glad to see such a full room at 9:00 a.m. That's actually encouraging. This is session 208. Andrew, Michael, and I are going to be talking to you today about securing iOS applications. And to be a little bit more specific, we're going to talk about how to protect the user's data at rest on the device, as well as when you transmit it across the network.

So we are all in the embedded data security team. That's really only one of the things we do, but that's the one that we're focusing on today. And so any time a key is present on a device that actually protects the user's data, some of our code is involved. It's the stuff that we actually care about. And so features that you may have heard of or may already be using are such as data protection, the key chain to protect secrets for connecting to websites, secure transport, which is our SSL or TLS implementation. I will use SSL and TLS interchangeably. And CMS, which may be less visible, although now in iOS 5 you can see S/MIME. And even iMessage, but we won't get into that today. So generally we start with designing and building implementations for, doing implementations for internal clients to satisfy their needs. But then after those APIs basically become better fleshed out and we've seen them work well, obviously we want to make these high-level APIs available to third-party applications and hope that they will adopt them as well. So today we're going to spend some time looking at these APIs and trying to show you how to use them. And what we want to do specifically is we're going to take a test application that we wrote for this presentation and we're going to show you what happens when you test drive this through a bad neighborhood. We want to show you why protecting the user's data is important. So we'll show you what can happen with a very basic application. Then you'll probably notice what kinds of issues can occur and you'll see why that matters. And then finally we want to show you how can we iteratively improve it. So we'll go through a couple of cycles to show you what we can do to make it better.

So the application we have for you today to demonstrate is called Oversharing. And it's basically a simple device-to-device photo sharing app. We didn't try to make, like, any UI demos. This is really focusing on the crypto below it. But what basically happens is these devices will be able to discover each other using Bonjure, tell each other, like, hey, I'm interested to see your pictures. And then any time the other device that takes a picture, it sends it back to the requesting device and says, like, here's another picture for you. So the source code is not available on the website, but we will take it with us to the lab. We'll skim really the surface and talk really about the high-level calls that you'll be making, but there are, of course, a lot of details that come into place to make the application work. So if you're really curious to see how that works, please meet us at the security lab. That will actually be right after our session. Another thing to ask is we will be using Wi-Fi, and so if anyone brought, like, a Wi-Fi base station with them and sitting, like, right in the front row, If you could turn it off, that would make it probably better for us than the demo gods. We'll hope that it all pulls through. Thank you.

So why would you secure this app? I mean, you could say, well, it's just a fun app, right? I'm just using it to share some pictures. But after you send your app into the world and a customer downloads it, of course, there may be other things that they do with it. They may potentially take an embarrassing picture. If they take an embarrassing picture, well, they're in for a bad surprise if it turns out that their picture can be caught in midair or basically pulled from their device. So you have to kind of assume that a user may use your application for any purpose necessary and that they may actually care for you to protect their data. And as we'll see today, the steps necessary are really not that hard, or at least that is what we'll try to convince you of today.

So, the threats that happen are a little scary and abstract. So, when we talk about brute force and man in the middle, you've also seen those in the news, and you may have thought, like, well, you know, yeah, it's bad, but I don't really know what it means. That's another thing that we want to try to show you a little bit more up close, that these attacks are fairly practical. And besides that, These threads are real because, well, you've potentially lost track of your device and had to call it and then retrieved it from the couch and suddenly it's like, oh, okay, there it is. But you had that moment of, oops, where is it? Well, another thing that may happen is you may know someone that lost it at a conference. Could happen. So it can be out of your control for a while and someone can go ahead and do everything that we'll show to you today. So lastly, your device is networked and it will really get all of its data and send all of its data over the network. There is really no other way to go and there is no such thing as a secure network. There really isn't. You can have a secure transmission across the network, but networks themselves cannot be trusted.

So how can our APIs help you? We're going to do this in three large sections. I will start covering the securing of network connections, which is pretty much the securing of transmissions across a network. Then we'll talk about protecting data. This is protecting of data on the device, so pictures that you've taken and stored locally, as well as protecting secrets. And secrets generally are credentials that you may actually use to retrieve additional data from the network and you may cache it on the device. but those secrets actually protect the data that the device pulled off of the network, and they're equally as important to protect.

So, starting with the section on securing network connections. There are two levels of APIs. There's really, there's high-level APIs, which we'll talk about from the client side, and there's low-level APIs, such as secure transport. The high-level APIs do everything. They basically start with, you give it the URL where you're supposed to go to, and they actually find the other host, open the network connection, send all the data across, and send you the data back, present it to you on a platter, and say, like, there you go. But of course that may not always work for you. We also have secure transport under the covers, which takes part of the HTTPS portion when you use the high level API. And what it does is really just implement the SSL protocol. And it does so by having data callbacks so that when you ask it to do something, it goes ahead and asks you, here is a packet of data that I'd like you to transmit to the other peer. And when you receive information, you will basically be giving that back to the stack via another callback. We are making secure transport API in iOS 5. You may have already seen it on the desktop, and you may have even already used it because you noticed, "Hey, it's right there. I can use it." Please have a look at the header that we made public. We didn't make everything public because we feel that there are some APIs in there that may set you off on the wrong path, and we've tried to keep it somewhat simpler. The biggest reason, of course, to make it public is we've added DTLS, which is basically doing SSL over datagram sockets. And there is no real high-level support for using datagram sockets. It's all TCP connections. Again, it's a very specific topic. I encourage you to come meet us in the lab if you want to hear more about that.

So let's talk about our application for a moment. Our application is going to work in the following way. One device is going to send an HTTP GET request to another device that it sees on the network using Bonjur. And then as soon as that other device has acknowledged this other device, it can send back via a post. It will actually start publishing pictures back to the device that requested the pictures, and it can do so continuously. So it will basically push its pictures out to the person that asked about them.

So how do we do this using the high level API? First, the get request. You start with the URL. The URL here is already prefabricated. Of course, in our application, we will need to fill in which device that is. So the address that we put in here is fictitious. We are going to basically do a lookup and insert that host in there. Then we are going to create an NSURL request.

And to create an NSURL request, which holds all the state around this request, you first need an NSURL. But an NSURL is easily created from the string. and then we have our NSURL request. Now at this point, you have the request, and the way that you can manage this thing, there is an NSURL connection, which is kind of a manager for the request object. You hand it to this NSURL connection, and it takes it through the paces. It goes through all the various steps that are required. And as it does, it is specified the delegate, which is your controller, and your controller can then basically implement the protocol called the NSURL connection delegate. And so that sounds potentially difficult, but really what it does is it implements very simple calls like did receive data. Whenever this request has been run, data comes back to the device, the callback will be called or the delegate will be invoked on your controller and it will present you with the data. Or if something goes wrong, there's of course the failure message as well to let you know like this request didn't go anywhere and that will of course be the end of it. There are additional methods that we'll get to later, but let's continue with the post request.

The post request is very similar. We start again with a URL. We turn it into a mutable URL request because this time we don't want a get request. We actually want to post data to the other side. So after we've created the request, we need to make a couple of modifications. One of them being, this is a post. We're actually pushing data out to the other side and we're setting the image data up as the HTTP body to present it to the other side. So the picture that we've taken, we convert it into data, set it as the body, and then send it. So with that, I'd like to invite my colleagues, Andrew and Michael, on stage so that we can demo to you how this app basically works.

I will be using the iPad that is tethered, so I will be tethered to my booth here a little bit, and Michael will go out. So let's see if we can-- yep, there's my application. We're going to connect to each other. I'm going to go around and look, and there's Michael's iPad, so I connect to him. He's going to do the same. He may have already connected to me. I'm set. And so what we can do now is ask him to take a picture.

I told them not to take pictures of me. And there's a picture. Alright, so we can do this the other way around as well. Let's take a picture of the audience, because I was playing. Wow, we get a nice star effect on there. And you may not be able to see it, but there's a couple of streaks on there. And well, you know, we can keep going. - I'll take one of the audience. - Of course, gotta embarrass Andrew. That was the picture you sent? Yep. Oh. I thought, oh, that was a different one. Okay. One last one? Sure. Sure.

So with that, I want to turn it over quickly to Andrew to let us know how we are doing. So I'm fascinated about what these two gentlemen are sharing, and I really want to get my hands on those images. So I've been in the coffee shop, these two gentlemen are sharing images, and I've got my own set up on the same wireless network. Or I could be another colleague wanting to snoop on this, or just driven to evil intent by the prospect of doing a live demo with packet capture. So I walk over to my device and we've got some images that I've just pulled straight off the wire. This was done very easily. I didn't actually write any custom code myself. Simply a script which recombines TCP flows, dumps out to a file, strip off the HTTP header, run it through the file command. Is it a JPEG? Yes. Rename it, let Finder do the rest. Very simple. It doesn't require a huge amount of technology to perform an attack such as this. So I am seeing that maybe there's nothing interesting being sent over at the moment. But if I wait a bit, maybe I'll get some of those juicy images.

So that was our first demo. This was for most of you probably obvious, we're sending data across the network, but at least now you saw that it's actually not that hard to intercept. So what happened? We connected to each other, we didn't use a secured connection, and the network is kind of like this room, anyone who has a conversation, anyone else can overhear it. And in this case, Andrew was right there to pick them up. You noticed some of the pictures were like a little choppy, but of course that has everything to do with how you make the packet capture reliable, and I'm pretty sure that there's people in this room that can do better than me. So, how are we gonna improve this? Well, on the client side, this is really simple. I already kind of hinted at it. If we use HTTPS, this high level request will go down and use secure transport to make an SSL connection.

So on the client side, it's one letter change, great. But let's talk about the server for a moment, because as you realize, these applications, of course, have to also implement the server. So for that we're going to quickly discuss secure transport. Now to set up secure transport, there's first some setup steps that are necessary. There is a SSL new context that creates the object that holds all the state for an SSL connection. After that, there are the callbacks that are needed, the callbacks whenever we want to send out some data over the network, or if we want to actually get some data from the peer to see whether they send us some data. That is the SSL set IO functions, and it will have a couple of callbacks. I refer to the sample code see how those callbacks are supposed to work. They have some detail necessary to them to understand how they work. Of course, you may already know from the desktop how they work, but the application will illustrate that more closely. Of course, just having these callbacks, you may want to reuse them for multiple connections. So there is also an SSL set connection that allows you to set a context object for this particular connection. So that any time your callbacks are invoked, you will be told this is the exact connection that we're talking about.

It's just a void star, but you can basically cast it to whatever you want under the covers to go find all your state again. And finally, we need to set up the certificates. We're going to deal with that a little later. After you've set up the connection, it pretty much works like any file would. It's basically an open, read-write, close cycle. SSL Handshake will go ahead and set up the secure connection after it's done, which may take a couple of steps.

you can call SSL read, which will read the unencrypted data from the other side, if some has arrived, and SSL write to send data to your peer. And finally, you can call SSL close again to say, "Okay, finish up the connection." That will only finish up the secure part of the connection. The network connection, of course, continues to be open to send more data across it. So this will only shut down the secure part of the connection.

So I skipped certificates and most of you may say like, well, you know, certificates is difficult. I don't want to deal with this, but it's actually relatively easy. But if you skip certificates, you may find like, hey, yeah, I can do that. I can use this one cipher suite here. It doesn't require me to set up a certificate. And so our example here is an example that uses a Diffie-Hellman key exchange, which is secure between two peers. The two peers will share the same secret at the end of it and nothing else. Then you get the AES encryption in CBC mode with 256-bit keys. That seems rather hard to brute force. And, of course, all your packets are protected by an HMAC using SHA-1. So anything that's modified uses yet another key to make sure that you can detect these modifications.

This is of course encrypted, but it's not secure. If we make this connection, say Michael makes the connection to me, as shown here, we know that there is a connection between the two of us, and when we send data across, no one else can really easily see it. They see a bunch of encrypted data flying across. But why is it not secure? Well, imagine that Andrew switches from a passive attack to a more active attack. Now, whether he does this by faking Michael's endpoint so that I accidentally connect to the wrong IP address, or whether he does this by having an entire environment up, like, say, this rogue base station of his that we're sitting on, and he manages in such a way that basically he can put himself perfectly in the middle of us, what will happen is Michael will connect to Andrew. He'll do this Diffie-Hellman key exchange.

He has a secure connection between him and Andrew. He doesn't know that it's Andrew. Andrew goes ahead and makes a connection to me. I don't know who's in the other end. And if Michael sends a picture, I see the picture. So what has happened now is like, Michael and I are none the wiser. We have the connection set up, we know that it's secured, but Andrew's still seeing the pictures. That was not what we set out to do.

So, certificate authentication. We're going to go back to that because it's actually relatively easy and that way we can stay within the realm of HTTPS. You can, of course, implement your own zero-knowledge protocol over an anonymous Diffie-Hellman connection, but again, let's show you how to do that easier and just stick with TLS. So, for certificate authentication, we're going to use asymmetric cryptography and it's going to use an asymmetric key. An asymmetric key is different from a normal key. In normal crypto, you use one key, you encrypt a bunch of data, you get ciphertext, you use that same key, you decrypt it again, and there's the plaintext again. With asymmetric cryptography, you have a key pair. There's a related key, two related keys, there's a public key, and there's a private key. The public key, you can actually feel free to share it, it's actually part of how it works. And there's a private key that you must keep secret.

Now, how do we go through this? This is one of the models in SSL that happens, but it's the easiest one to explain. So what I can do is I can use my private key to create a signature over a bunch of data. What will happen is I create a checksum and then I do an asymmetric crypto operation which will sign it for me and give me the signature blob. Now if I go ahead and pass someone the signature blob, plus the data of course that came across that we signed, as well as my public key, the other party can happily take my public because my public key is not going to allow them to sign the data, but they can use it to verify that the data that was signed by me with my private key was actually signed by me. Now, this doesn't show you exactly, like, who I am yet. This only shows you how I can prove that I had possession of a key. So the "who" is actually where the certificates come in. If we zoom in on the certificate that we have, if you look at it at a very high level, There is actually our public key in there, which of course we needed to prove to the other side who we were. But then the who is not in there, the key is kind of an anonymous bag of bytes. So there's also an entity in there, something that talks about whether it is my SSL server, my web server or something. And so this combines basically the who it is plus what key they will be using.

That can of course be modified unless you go ahead and sign this. So let's use the same method that we just used to basically make sure that the signature is formed over the subject in the public key and add the signature to the certificate. It just sits there separately, but anyone who basically takes the public key that belonged with the private key that created that signature on it can verify that the subject and public key combination in the certificate were not modified. Now of course it would be pointless if we did this to our certificate itself because, well, then, you know, we can only trust it based on this one certificate. So generally speaking, there will be someone else's private key that signs your certificate. And so you can form a little tree.

This root certificate that came into view basically has a public key in it and a private key that someone else holds. And they went ahead and put the signature on my certificate. Now, anyone who trusts this root certificate will also be able to authenticate all the certificates that it issued. Now, for that, our devices actually trust an awful lot of certificates. So there's about 250 now, so that makes it a little awkward. But basically, that is the trust pool where we start from, and as a result, we can trust the leaves that are dangling off of this large tree.

So, Michael and I work at Honest Apes. We already have our configuration profile installed. We actually have our own CA in-house that, you know, bicycles can only make you that much money. So, we decided to open up a certificate store here as well so that, you know, saves us some money. But we basically have ACA. So, we have our two applications. Our applications both need a certificate to connect to each other. So we're gonna take the root certificate and we're gonna issue ourselves two certificates and basically add them to the application.

So in SSL, when you normally use it, only the server really authenticates to you. When you use a website that's okay because the information is technically public. You only want to know when I go to this particular source I want to see something that is actually theirs not someone else's.

server authentication, if I connect to Michael, he is going to authenticate to me. And thereby, I know this is Michael. But in our situation, that's not enough. Because imagine that Andrew connects to Michael. No problem. Michael will authenticate to Andrew, but if he actually starts sharing pictures, he would actually be happily forwarding pictures to Andrew, which was kind of the point. We were trying to make sure that Michael and I I could share pictures without Andrew seeing it. So the only thing that server authentication does in this scenario for our app is it avoids me connecting to Andrew and getting, for example, a LOL cat sent to me instead of a picture that Michael taught.

So if we do client authentication, Michael will also authenticate to Andrew. And so as he authenticates, or it requires Andrew to authenticate, sorry. So as Andrew tries to authenticate, Michael notices, hey, this is not Conrad, and basically drops the connection. So that stops it from happening. Now for our main scenario, of course, that will still work because as Michael asks me to authenticate, he'll notice like, oh, that's Conrad. Okay, good, we can make this connection. And then in the future, he can start sending me pictures because he knows that he talked to me before.

And in future connections, I am the server. He'll know that's Conrad that I'm sending to, and I'll know that Michael is actually sending me pictures instead of Andrew sending me wall cats. So now we have mutual authentication. How do we do this? So we're going back to our delegates.

Whenever our delegate is called for receiving, before our delegate is called for receiving data or errors that happen during the connection, there are a couple of authentication challenges thrown our way. The first of which is going to be for this client certificate. So the delegate is called, did receive authentication challenge, and it passes us a challenge. Now we can inspect that challenge and notice that what it's asking us for is I want a client certificate. The other side asked us, like, hey, please authenticate yourself so I know that I want to send data to you. After this happens, we create a credential and actually just set it. Fairly simple. Now, how do we get here? You see us creating this NSURL credential, and we're creating it with an identity. Identity is really very simple. It's just a composite object that really just puts together my private key as well as my certificate.

If you put those two together, you know, for logical purposes, we have this identity object, and that is what you create the NSURL credential with. Now, you could also pass along more certificates, but that's another detail that I don't want to get into right here. That is also not necessary for our basic mutual authentication, as you'll see.

Before this delegate is called, there's one performance optimization that is pretty much a, are you going to handle this particular authentication challenge that is called first? So the first thing URL connection will do before it even asks me for a client certificate is ask me, like, do you support that? And so when that is being called, I return yes, and off we go.

So let's demo how our application works with SSL enabled. All right, so there's my device again. We're going to connect to each other again. You notice that really nothing has changed. Thank you. I'm connecting to Michael. Michael probably connected to me. Maybe he can start with the pictures. Oh, not me again. All right, well, great. There's a picture of me. Now I'm going to pass the buck right around and go back to Andrew.

one more for the audience because you guys have been so patiently listening, should be All right, well, as you saw, we basically managed to use the app without any other thing. It worked the same way as it did before, and that's pretty good for us as users. So let's see what Andrew got.

So I've noticed that Michael and Conrad are back on my network and I've been running the same utility I was running earlier. And let's see what we've got. Lo and behold, I have no more images. Well, I could see them using the application, so what's going on? Maybe my little setup here is broken.

But if I go to my intercepts folder, I can see that, yes, I've got some traffic here. But if I look at it, that's very odd. That doesn't look like-- a JPEG, in fact it looks incredibly encrypted, so maybe they're doing something else. At which point I could go in and say do a traffic flow analysis and perhaps use the Wireshark utility and I can see, "Ah, they're using TLS." Out of that I can get information such as the certificate, because that goes over privately, and I can find out that they're using their company CA, which is Honest Aves. And as it happens, I happen to know somebody who works in the IT department of Honest Apes. He's mostly just a bicycle repairman, but he does it on the side. And as a favor, I said, "Hey, you know, I've got these friends, Michael and Conrad. Can I have some certificates for them?" And lo and behold, I got them.

So whenever I did the attack that Conrad just described, where I actively man-in-the-middle'd, suddenly I can pretend to be Michael to Conrad and pretend to be Conrad to Michael, because I have those certificates. So I'm back in the game. I can now read the traffic without alerting them to the fact that I'm there on the network, because I've done something to steal the certificates. Now, this isn't terribly common, but it happens from time to time. So, well, we kind of knew that that was common because, well, using this certificate authority was, of course, very easy, but that was too easy. Now, how are we going to deal with this situation? It's really not that hard to get out of that problem. You know, certificate authorities are out there, and generally you can trust them. But say that for this particular purpose of the application, we don't really want to deal with them. We just want to use a secure and authenticated connection between our devices. So how can we rule out man-in-the-middle in this case? Well, we're currently trusting all certificates. So basically whether it was HonestAbes or any other one, our connection would have basically been authenticated and we'd go like, "Yeah, okay, that's great, that's fine. "Let's just send the pictures across." So what do we do if we want to trust just the right certificates? Well, there's one thing we can do, which is, well, let's limit the root certificates. We could have already limited it to HonestAbes, but we don't want to deal with HonestAbes anymore, so let's just put our own one together for the purpose of our devices authenticating this application.

And so how are we going to limit the root certificates to this hierarchy of our certificates? Well, we're right back at the authentication challenge that we were getting from URL connection. This is actually the same method as you've seen before where we specified the client certificate. This case, this time through though, it will tell us like, hey, do you want to deal with the server trust? So basically, the time when we first trust the certificate, the client certificate we used to authenticate to the server, now we're going to deal with the case where we connect to the server and the server first authenticates to us. We're going to say like, yes, we want to handle that situation as well, we don't want to deal with the default, and then how are we going to handle it? Well, when we get calls for the server trust evaluation, we're going to pull out a SecTrustRef out of the challenge. The SecTrustRef is again a composite object which really contains the policy for the type of application we have, but mostly the certificates that the other party send across the network. And the other thing we can do with this trust object is of course see whether we trust it, do a trust evaluation which will build the appropriate chains, see whether we trust it. Now the one modification we wanted to make to our trust evaluation is not trust all certificates. We just want to trust the one root certificate we set up for all of the users of oversharing. So we're going to do that by calling SecTrust set anchor certificates and we're going to pass it this oversharing route that issued all these leaf certificates to the oversharing apps. Then we're going to evaluate this which will build a chain up from the certificate we received from the server and find whether we actually go and match up any of the certificates we passed as anchors which don't necessarily have to be root certificates, it just needs to be if we follow up the chain using all these certificates passed by the other side, do we find this oversharing certificate. And then after we evaluate that successfully, we get a result back. That result is unspecified. Don't let that worry you. This actually means it's all good. If there were Honest Abe's route involved in this case, you would get something like a recoverable trust failure, which would let you know it's recoverable if you were to trust Honest Abe's route, but you're not, so it's a failure.

At the end of it, we do the same thing as in the other one, whereby we specify back to the delegate, like, "Okay, let's create a credential out of the trust that we've evaluated successfully," and pass that back. If we do not trust the other party, we return nothing. And as we come out of this delegate, the higher-level APIs will close the connection and basically flag the error up to your application.

So in summary, I think I've tried to show you that HTTPS is fairly easy to use from the high-level API use, and it does require some setup work to use these certificates. But it provides a simple experience, which only adds to oversharing and remaining a fun application. If you have to dig in and get some more things out, Secure Transport has a host of options that you can use to optimize for your purposes and other methods of authentication. But of course, you have to watch what you're doing. Again, hit us up at the lab if you want to discuss those options, and we can help you with those. So finally, let's see what happened now that we restricted our routes. I do not trust Honest Abe's anymore. Let's see what happens when I go ahead and try to go across the network. Imagine that Andrew is sitting there with Honest Abe's certificate, and he's publishing Michael's name, and I'm just connecting to him.

And as I go ahead to connect, I basically get the error back up at the top level of my client, which is "did fail" and there are some additional information passed to me which says like, "Well, Michael's iPad, we don't trust it. That certificate that you're using, we're not currently trusting anyway." And an unhelpful suggestion of would you like to connect anyway, of course I don't. I want to keep this connection secure. So we're going to cancel out and leave it at that. And hopefully we'll find a network where we can share pictures without Andrew getting in the middle.

Thank you. So now I really am lost. They've completely secured their network connection, and I can't get in through that method at all. However, very handily, as Michael walked off stage, he left his iPad here, and he forgot it. So, well, what can I do with this? Of course, by default, there's no way I can get at the raw file system on a device. but the files are just there in plain text, and if there's something such as a forensics tool or jailbreaking or some other utilities, I might be able to get at the raw data on the file. So let's see what we can do there. So there might have been some pre-demo setup here, but I've just plugged it in. And let's run this demo tool and see what happens. Oh, we have some images coming across. That looks interesting.

Lo and behold, it looks like the images that were sent earlier. So even though I am now forced to no longer attack them on the network, I can attack the device if I can get physical possession. It sounds like maybe there's some work to be done there, but at the moment I'm still happy.

is how to protect data going across the network. And as we've seen, that's not really entirely enough, because if I lose my device, well, that data's not protected. So, as it turns out, we've actually built something into iOS 4, and it's actually enhanced in iOS 5, called data protection. And data protection lets you protect the data on the device at rest. And it does this by tying the data we're protecting to the user's passcode.

protects that data in the case the user loses physical possession of the device, assuming you set a passcode on that device, which obviously I had, but since our application wasn't using data protection, Andrew was able to get access to all that data. And as Andrew pointed out, there's widely available hacking and various tools that will let you access the file system. So without using data protection, there really isn't much protecting your data.

or in this case, your customer's data. So the way data protection works is, we have a file on the device. That file is encrypted using a randomly generated file key. Then the file key itself is encrypted with a class key, which is also a randomly generated key. And that class key is in turn protected by device key on the hardware and the user's passcode. Those two are scrambled together using a special algorithm that makes it hard to, or hard or impossible to offline attack the user's passcode. It basically forces you, when you want to brute force the passcode, you have to brute force it on that particular device, because the device key is a per device key that can't be extracted out of the hardware. So this makes it that if your password is strong enough, if the user's password is strong enough, their data would be protected, assuming that you guys actually start using data protection.

There's a number of APIs in iOS 5 that support data protection. There's the NSFileManager APIs, and basically there's a key added there called NSFileProtectionKey, and there's various NSFileProtection options to that key, which I'll go over. CoreData has the same key and has the same options. NSData has the same options, but they're called NSDataWritingOptions instead, but it's the same exact functionality. We even added it to SQLite, So if you're creating a SQLite database directly rather than using core data, you can create a data protected SQLite database. And secitem, which is the key chain interface, also has data protection. And this is historically, those are called attribute accessible. So they're described as accessibility rather than protection, but I'll show you the mapping between the two. They're the same.

Now, these APIs are nice, but for probably 95% of the people in this room, your applications only run in the foreground. So when the user clicks the menu button, the application goes away, your app isn't really doing anything in the background. For those apps, adopting data protection is as easy as adding an entitlement called data protection class and setting that to NSFileProtectionComplete as its value.

At that point, all of your application's documents and files that it creates will automatically be protected with the highest data protection class available, which is ProtectionComplete, which basically means that none of your application's data can be accessed unless the device is unlocked at the time. So as soon as the user hits the lock button, about 10 seconds after the lock timeout goes off, so you can set in settings, you can set go to sleep immediately or after one minute. Once that timeout expires, apps get about 10 seconds time to clean up, write their files. At that point, the keys are thrown away by the kernel and there is no way to decrypt that data unless you re-enter the user's password. So this is what probably almost all of you should go do today.

And then profit. So now let's say you're not in the class of app that just runs in the foreground and you actually need to use some of our APIs because you have some files you need to access in other cases. So here's an example of what we would use in our application here to write an image to our album. And what we do is we get the data out of the UI image and then just call NSData's write file to path with the data writing file protection complete option, which makes basically that image protected and only accessible when the user's password is entered and the device is unlocked.

So some things to consider is that, again, data protection is only as good as the user's passcode. So if you have A as your password, it's not going to be very good. And even though we limit the speed at which you can brute force it to about 10 tries per second, if your password is a four-digit PIN, that's only, what, 10,000 options. You can go through those in a couple minutes. So users do need to choose a somewhat longer passcode for it to actually make any real benefit.

And as we said, you can't access these files when they're locked. And you can't create them when they're locked. Now what if your application needs to be able to create files while the device is locked? Let's say in a case of our oversharing app, we want to receive images while my device is in my pocket. So I connected to Conrad's device, but I put my device in my pocket. Conrad's taking pictures.

I still want them to be stored on the device and archived. Well, since it's locked, I can't create files with NSProtectionComplete. For that, we have another class called NSFileProtectionCompleteUnlessOpen. Under the covers, that actually uses an asymmetric key pair to protect the data. So what happens is the private key is protected by the password, but the public key is always available. So the system is always able to create new files.

And as long as you keep that file open, the kernel lets you read and write to that file. As soon as you close the file, the key for that file is thrown away and the only way to get it back is with access to the private key. And since the private key is protected by the passcode, if the device is locked, you can't reopen the file. Now because it uses asymmetric Kipto, it puts a slightly heavier load on the system. So as a general policy, it's good practice to upgrade those files to protection complete the next time your app is able to do so.

I'm going to show you how to do both of those things. Here's the write images while locked method again. This is the version that actually works even when the device is locked. First we try to write the file with protection complete. If that fails because the device is locked, we just write it with complete unless open. That's basically all there is to it.

So as far as the startup code that we have to do to upgrade things, We start with looping through basically all the files in our album directory. And for each file that isn't already protection complete, so we look at the file attributes, if it's not protection complete already, then we create a dictionary saying, set the protection key to complete and set the attributes on the file. So this is using the file manager APIs to basically modify the protection class of existing files.

So there's a third class of apps, which what if in addition to receiving pictures while we were asleep, we wanted to actually provide some kind of album service that people could connect to after the fact and download pictures. That means that someone would actually be able to -- need to be able to read files while the device is locked. Now this is a class that we'd rather you not use unless you really have to because the The downside of this protection class is once the user enters their passcode, all files of protection complete until first user authentication are accessible to the system until you reboot the device. So what this means is if you took your phone to like through airport security in some country where you're not really sure what they're going to do with it, if you power it down or restart it before you hand it off to the customs officer, these files are protected. If your device is just locked, then in theory, they could still pull those files off using a forensics tool. So, but there are cases where you need to use this, which is why we provide it, because it's still better than not protecting it at all. So, the example case in our case would be, we're making a background service that lets you download images.

So here's how we would make a SQLite database that can be read and written even when the device is locked. So let's say your application is something that runs all the time in the background, some kind of system service, then you could create a database using file protection complete until first user authentication.

So with that, I'm going to bring Andrew back on stage to see if he can hack into our app now that we have some data protection enabled. - So, yet again, that careless chap Michael has left his device lying around, and I've got hold of it. So, let's take a look and see what I can get off it this time. This time it appears to be locked. And there's a-- these are set up the same-- there is a long password set on it. So let's see what we can get off it.

So this time we're running the demo tool and we get operation not permitted. And that shows that while this device is locked, I can't get in. And the chances of me getting to the device before that 10 seconds elapses is quite small. However, say for example you are in an airport and there's a charging station that happens to be hanging out of the wall. And you think, okay, I better lock my device before I put it into this charging station.

I don't quite trust it. Make sure you wait those 10 seconds for those keys to be thrown away. And you also might think, well, we use flash storage on here, and it's very difficult to properly get rid of keys. You might have heard that's a problem with some issues. But we've actually created a special part of there where the keys can be easily thrown away, and we can guarantee they're overwritten.

And for brevity, I think I'm going to leave it there. But I'm now fully locked out of that device and my evil plans to steal the embarrassing pictures have been thwarted. So Now we've seen how to use data protection and you think well, that's great now I know how to protect all my data. So if I need to store a password, I'm just gonna write it into a file that's data protection complete and that's where we kind of want to make a little change because we have another API here called the keychain and And to talk about what belongs in the keychain is, as Conrad alluded to earlier, what belongs in the keychain are secrets.

And what we consider secrets versus data is secrets is anything that would give you access to additional data. Say, you know, a credential that you need to log into a service or a key that you use to encrypt something. Those things would be stored in the keychain. The keychain has actually been around since iOS 1, and the keychain has always been our most protected layer in the system.

So, Keychain has, in addition to data protection, some higher level controls that let you control migratability, it has different access groups, so it's partitioned between applications, and there's some other features of the Keychain that make it something we'd rather see used for credentials than just storing them in a file. So, example would be, you know, storing a username and password because we want to add functionality to our oversharing app to upload pictures to the system.

rather than asking the user for their password each time, we store those credentials in the keychain. How do you do this? Well, you use the keychain interfaces. And the way you protect the data in the keychain is you set the accessibil-- the atter accessible, which basically tells you when you need to be able to access-- or you're telling the keychain when your application needs to be able to access the data. And if you say, I only need to access the data when unlocked, that's equivalent to data protection complete. If you say, I only need to access the data after first unlock, that's equivalent to complete until first user authentication. And then finally, there's always, which is equivalent to no data protection. So the default for keychain, if you don't set the accessibility attribute, is when unlocked. So it's the highest protection level.

By default, these classes also let keychain items migrate, which is to say, if you backup your device and you've set a backup password, and you restore that backup to a different device, any items marked with any of these accessibility attributes will show up on that new device. Most of the time, that's what you want, if it's a credential or a password. Sometimes the credentials or keys or whatnot you're storing in your application might be bound to the device itself, and you would want to get new credentials when the user gets a new device. So if you need that, there are variants of these where you append this device only to the name of the accessibility attribute and that prevents those items from migrating to a new device. If you backup your device, wipe the device and restore the backup to the same device, those items still stay there, but they won't migrate to a new device.

I want to show you an example of how you would use a keychain in your application. And so for that, we start with a little helper function that we're going to use everywhere called query for account. So this is in the case of our oversharing app. We're going to use a generic password item. Most of the time, you would probably be using an internet password item, which has a bunch more attributes. But for brevity, I'm using a generic password item here as an example. So we're setting the class to generic password. We're sending the service to oversharing, and we're setting the account to the account name on the service that in this case was passed into this function. So the password for account function is the first function your code would call. Let's see if we already have the password in the key chain. So first we get the query, then we add one attribute to that query which is return us the data please. All right. Now we say copy matching. Give me something that matches this query. And we get back the data for that item if it exists. If it doesn't exist, we get it.

then we would get back the error item not found. If we get back any other error than item not found, then the item probably exists, but we can't access it right now or there's some other problem because the device might be locked. So we wanna remember the fact that we didn't, did or didn't find the item here.

So the other function we need is, well, if the password wasn't in the key chain, we need to store it, we need to set password function. So for that, again, we call the query for account, which is the helper thing. Then we set the data attribute. So we set the value data that actually sets the password on the item, and then we set the accessibility attribute. And we say, we only wanna access it when unlocked, which happens to be the default, but it doesn't hurt to be explicit. And then we add the item.

And then finally we have the update function, which is very similar to the set. The difference is that this is what you would call to modify an existing item that's already in the keychain. Let's say we had an item in the keychain, but the password was wrong because the user changed their password on the server. You prompt the user for their new password, and then we update the keychain item when we're done. So for that, again, we get the query. Now we create a second dictionary, which are the changes we want to make to the item.

And for that, we're going to change the data to the new password, and we're going to set the accessibility attribute. It's important to note that whenever you call update and you modify the data, you must also set the accessibility attribute at the same time, or it will revert to the default. And then finally, we call sec item update. So putting this all together, the high-level sample code would look something like this. We start by looking up the password.

If we find it, we call our login method that actually tries to log into the server. If it succeeds, we're done. Now, it turns out the login didn't succeed. Well, then we ask the user for a password, and we try the login again. Presumably, if the login succeeded now, the user entered the right password.

If we had previously found the password in the keychain, we now update it. If we didn't find it, we now set the password in the keychain, and we're done. So, in summary, the reason we have this session, what we really want you to do is to think about protecting your customers' data. You here are all building applications for iOS. We try to give you the tools to protect that data, but in order for that to happen, you guys have to adopt some of these APIs we just talked about today.

So we want you to store credentials, secrets in the keychain. There's really no excuse anymore not to use the keychain. There used to be, prior to 4.0, keychain items didn't migrate if you had a new device. So that was the reason some developers were like, oh, we don't want to use a keychain because it's a bad user experience when the user gets a new phone. That's no longer the case. We want you to protect files with the best possible data protection class available. And again, the first example I showed you, if you're not running in the background, just set the entitlement. You're done. No code. And then finally, encrypt network traffic as appropriate. Here's a list of some of the reference guides, talks about the different APIs we touched on today that are related to security. With that, I'd like to thank you all for coming.