Strategy for generating and saving password for encryption and decryption - ios

I'm using the RNEncryptor and RNDecryptor classes for encryption and decryption as follows:
NSData *encryptedData = [RNEncryptor encryptData:input
withSettings:kRNCryptorAES256Settings
password:thePassword
error:nil];
NSData *output = [RNDecryptor decryptData:encryptedData
withSettings:kRNCryptorAES256Settings
password:thePassword
error:nil];
The first time I have to encrypt data in my app I generate a password using the RNCryptor class as follows:
NSData *thePasswordData = [RNCryptor randomDataOfLength:32];
NSString *thePassword = [aesPasswordData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
I save this generated password in the app's Keychain and use it for all subsequent encryption and decryption.
Is this a good strategy for encryption/decryption or can anyone see any flaws in it? Should I instead be generating an AES key and storing that in the Keychain and working with that rather than a password?
Edit: I changed above how I generate the password from using the NSProcessInfo class to using the RNCryptor class based on Rob Napier's answer. That aside I'm still curious to know whether the strategy in general of working with a password rather than an AES key is correct and secure.

This is not a good way to pick a password. globallyUniqueString can be quite predictable in many of its bits. You're much better off using something like RNCryptor.randomDataOfLength to generate a blob of desired length (32 bytes would be ideal), and then base-64 encode it to get a password.
Using randomDataOfLength to generate keys instead wouldn't really be any more secure, but it would be faster (by 10s of milliseconds depending on the device, if that matters to you). In general, I recommend using the password interface unless you have a special problem where keys are particularly helpful. Keys are just a little harder to use correctly.

The actual encryption key used by these libs is derived from the password, if you use one, but, IIRC, salted so it isn't intrinsically less secure.
There are concerns regarding the theoretical level of security provided by these libraries, (see How to correctly encrypt data with proper authentication using AES-256-CBC in php?) but you have to make a judgement call on that. Thing to bear in mind is that RNCryptor is a set of libraries (which may have published attack vectors in different implementations) AND a consistent format, which is useful if you want to move encrypted data across platforms.
Personally, I would feel more comfortable with using a unique, random AES key for each encryption and storing that key encrypted with RSA stored in the keychain.

Related

AFNetworking with no serialization

Good day everyone! I've been using AFNetworking 2.0 for a quite a while and because input was always of https with json - never had any problem. Yet now we have a custom written on C server which works only with HTTP and sends encrypted raw byte data.
As far as I understand it's necessary to use some sort of serializer , but i can choose only from: AFHTTPResponseSerializer/AFJSONResponseSerializer/AFXMLParserResponseSerializer/AFXMLDocumentResponseSerializer/AFPropertyListResponseSerializer and none of them seems to fit.
What's the best solution?
As result i need decrypted NSData which i can parse byte by byte.
All the possibilities of encryption rule out a standard ResponseSerializer. Some of the encryption properties include algorithm, key, key size, mode, possible iv and padding.
The solution is to decrypt the received data in a separate step.
In order to decrypt the data you need to know the algorithm, it's parameters and the encryption key. It is also possible that additional encryption information is added to the encrypted data such as an iv, KDF reputation count, etc. You need to obtain this information from the server developers.

Transitioning to New Encryption Algorithms

How can one transition encrypted data to a new encryption algorithm / settings in an iOS app? I'm not asking exactly how to do this with code, this is rather a conceptual question.
There are currently thousands of people using my iOS app to encrypt their data. I have found issues with the current encryption methods. In order to fix those issues I would need to implement an improved encryption system (see below for details) and transition current users to the new system.
I'm not sure how to go about migrating users to the new system without prompting them to enter their private keys, decrypt, and re-encrypt with the new system. Ideally this transition would be as seamless and as invisible as possible. If the transition does not work I fear that users will lose their data or become frustrated.
Old Encryption Method
AES 256-bit
CBC Mode
New Encryption Method
AES 256-bit
CBC Mode
Password stretching with PBKDF2
Password Salting
Random IV
Hash HMAC
Any ideas on how one could go about transitioning between these two AES encryption systems?
Are the current encryption keys good? If so you can keep them and wrap them with the new key deviation function. That allows the user to change their password without having to re-encrypt the data. If the keys are too weak you will have to decrypt and re-encrypt the data.
I see "Password Salting" and "Hash HMAC", you should be thinking more along the lines of PBKDF2 to create encryption keys from a user supplied password/pass phrase. Use the calibration function to choose the number of rounds.
If you were thinking ahead you have a version indicator and if so can just encrypt new data with the new key-scheme version and have backward compatibility.
I am wondering what Base64 encoding is doing in encryption other than to transport the encrypted data across an interface that can not handle 8-bit bytes such as JSON and XML.

iOS Hardware encryption vs own implementation

I am developing an app that stores PDF files. These files should be stored secure, i. e. encrypted. I also found some libraries that extend NSData with AES en/decryption. But then I read, that iOS supports hardware encryption via AES. Is the NSData library really necessary if they both provide AES256 encryption?
If there are differences, which way is more secure? Also.. how do I activate the hardware encryption? Or is this a global setting that applies to all apps? I guess that the files become decrypted after the device is unlocked? So if someone cracks my phone he has also access to the decrypted files? But if I do the encryption by myself and connect the decryption with a SHA hashed password that is stored in the keychain the files might still be inaccessible?
Edit:
Did I get it all wrong and my library (AQToolkit) is just some kind of API for the built-in hardware encryption and I am basically talking about the same thing?
I heartily recommend RNCryptor, which uses Apple's own Security.framework guaranteeing hardware encryption/decryption if possible. It's incredibly easy to use in the default case (AES-256 with 10k iterations of PBKDF2). It's not an encryption library per se, but rather an Obj-C packaging of the open source Common Crypto C library. Check it out.

GNUPG decryption in iOS environment

A colleague provided me two text files he encrypted using GNUPG, AES128/AES256 with no salt.
Using the following example, https://stackoverflow.com/a/1400596/300972, I tried to decrypt both files in an iOS application, one using the AES256 example, the second by modifying the algo to kCCAlgorithmAES128 and keysize to kCCKeySizeAES128.
Loading the files to an NSData object proved successful; I am able to output the NSData. However, on decrypt they always fail with kCCDecodeError (-4304). I thought it may be the padding, so we tried different variations, the original being kCCOptionPKCS7Padding, still the same error. I tried a padding of 0, which provides a truncated NSData object which I cannot create an NSString from. (UTF8 encoded).
Has anyone been successfully able to decrypt a file encrypted using GNUPG in an iOS environment? Can you provide us with lessons learned?
GnuPG writes in the OpenPGP file format (RFC-4880). This is a fairly complicated format and you would need to parse it before you can even begin to decrypt the data. GnuPG also compresses the data before it encrypts it. And it uses "OpenPGP's variant of Cipher Feedback (CFB) mode." While iOS 5 supports CFB, this isn't quite the same as RFC-4880. For instance, they don't use a normal IV, and they synchronize in a novel way to provide a "quick check" that is incompatible with standard CFB. Then there's their String-to-Key (S2K) algorithms, which are not the same as PBKDF2.
In short, CommonCryptor is the last in a long series of steps of tearing this down to something to hand to AES. You could look at libgcrypt, but its LGPL license is generally incompatible with iOS development. You should probably investigate other OpenPGP implementations. I know there are some in JavaScript (which is crazy, but could still work without creating licensing headaches). Maybe Cryptlib (which has a commercial license).
Personally, I'd go with some other encryptor if you can. OpenSSL, while not particularly secure, is very portable, and as easy to use as a commandline app. RNCryptor can read and write it on iOS.
You can check ObjectivePGP framework.

Confusion about Encryption in iOS

I'm a very newb programmer trying to write some iOS programs, and when I reached the part where I must encrypt my data, I ran into a misty and ill-documented wall. Apple apparently provides all the tools one needs to encrypt data but doesn't write about it anywhere. Currently I am experimenting with stuff found in https://github.com/AlanQuatermain/aqtoolkit, which apparently work. However, I read in http://robnapier.net/blog/aes-commoncrypto-564 that one should not use user selected passwords as encryption keys, but I have seen a few examples of people using the user's password directly with this library and others. Does this apply here, and should I run the user password through a small hurdle race before using it?
It is a good idea to use the hash of a password as a key for your crypto routines. One reason for that is that different algorithms may need keys of a different length and by selecting the appropriate hashing algorithm (e.g. SHA256 for AES256) you automatically get a key with the appropriate length.

Resources