3

I'm working on an iOS and Ruby on Rails application and need to transmit data encrypted from the iOS app to the Ruby on Rails application. My challenge is how to encode the data in Objective-C in a way that I can decode on the Rails side. I'm using the example in this SO question as the method to encrypt the data, and the example code shows what the encrypted data would look like this:

printf("%s\n", [[plain description] UTF8String]);

which creates output that looks like:

<3fe47b63 bd9a84ab 30dfb1a4 e409b60f>

My challenge is that I need to find a way to get this across the wire to the Rails application in a way that I can decode for use with OpenSSL code like:

def decrypt(data)
  cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
  cipher.decrypt
  cipher.key = cipher_key
  cipher.iv = cipher_iv
  decrypted_data = cipher.update(data)
  decrypted_data << cipher.final
end

I'm thinking that Base64 encoding may be the best way to go as this data will end up in an HTTP header in JSON requests. It seems like I could use Base64.decode64 to decode the data on the Ruby side and pass it as the data to decrypt, but I'm hoping someone can guide me on whether this really is the best way to do it and, regardless of the encoding, how to turn a pointer to an NSData object like this:

NSData *cipher = [plain AES256EncryptWithKey:key];

into that encoded value to get it to the Rails app. Thanks!

Community
  • 1
  • 1
Chris Hart
  • 2,153
  • 1
  • 23
  • 45
  • 2
    Because HTTPS only encrypts the traffic... By providing a signature on every request, it's much more difficult for someone to maliciously make requests that make it look like they are coming from the iOS application. – Chris Hart Jul 22 '12 at 01:59

2 Answers2

12

You can use the standard AES encryption. Here are the libs with AES-256-CBC cipher and Base64 encoding that you can use across both platforms quickly:

Ruby

https://github.com/Gurpartap/aescrypt

Here's how you would use the AESCrypt Ruby gem:

message = "top secret message"
password = "p4ssw0rd"

# Encrypting
encrypted_data = AESCrypt.encrypt(message, password)

# Decrypting
message = AESCrypt.decrypt(encrypted_data, password)

Objective-C

https://github.com/Gurpartap/AESCrypt-ObjC

Here's how you would use the AESCrypt Objective-C class:

NSString *message = @"top secret message";
NSString *password = @"p4ssw0rd";

// Encrypting
NSString *encryptedData = [AESCrypt encrypt:message password:password];

// Decrypting
NSString *message = [AESCrypt decrypt:encryptedData password:password];

Good luck!

Community
  • 1
  • 1
Gurpartap Singh
  • 2,744
  • 1
  • 26
  • 30
4

I ended up going the Base64 route. I used the NSStringAdditions base64FromData method in another SO answer:

+(NSString *)encryptToBase64String:(NSString *)data {
    NSString *key = <key here>;
    NSData *plain = [data dataUsingEncoding:NSUTF8StringEncoding];
    NSData *cipher = [plain AES256EncryptWithKey:key];
    NSString *str = [NSString base64StringFromData:cipher length:[cipher length]];
    return str;
}

Then added the base 64 encoded string to the RestKit HTTP header:

[[RKClient sharedClient] setValue:encryptedTimestamp forHTTPHeaderField:@"<encrypted_header_value>"];
Community
  • 1
  • 1
Chris Hart
  • 2,153
  • 1
  • 23
  • 45