decrytption in ios 7 not working using aes - objective-c

In My App, i'm getting data from xml, where it is encrypted, and i need to decrypt the received nsstring,
UserName = #"QEjbHvzPjk+YuLDVPUJuEA==";
I Need to decrypt this nsstring into regular format, i searched and find aes , but it doesn't make any changes,
NSString* msg = [FBEncryptorAES decryptBase64String:UserName
keyString:#"01234567890abcdefghijklmnopqrstuvwxyz"];
if (msg)
{
UserName = msg;
NSLog(#"decrypted: %#", msg);
} else
{
UserName = #"(failed to decrypt)";
}
How can i decrypt the above nsstring, Thanks in Advance.

The string is not only AES encrypted, it is Base64 encoded. The trailing "==" is typical of base64 padding. Also AES encryption produces data bytes, not ASCII characters and the output is a multiple of the block size. It is common to Base64 encode the result of encryption so it is ASCII and can be included in XML.
For iOS 7 there are several Base64 API methods for NSData. Probably what you want is:
- (id)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options
Example:
NSString *userName = #"QEjbHvzPjk+YuLDVPUJuEA==";
NSData *data = [[NSData alloc] initWithBase64EncodedString:userName options:0];
NSLog(#"data: %#", data);
NSLog output:
data: <4048db1e fccf8e4f 98b8b0d5 3d426e10>
The data probably is AES encrypted, it is a multiple of block length, and if so you will need the key and also information on padding, mode and possibly iv.
Note that the FBEncryptorAES class method encryptedBase64String does accept Base64 input but the decryption key string is suspect and the encryption may not match this decryption method due to method and possible iv. So the FBEncryptorAES class may not be what you need.

Related

Decryption of base64 encoded data objective-C

I have been working on this for a while, but can not find a way to tackle the problem. Hopefully one of you can tell me what I am missing.
I am using NSURLConnection to download base64 encoded data containing AES128 encrypted data. What I have is the key, see code, and the knowledge that the first 16 characters of the encrypted data is the IV. What I want is to decode the data and then decrypt it using the key and iv extracted. This is what I have so far:
- (void) connectionDidFinishLoading:(NSURLConnection *) connection {
NSLog(#"Succeeded! Downloaded %d bytes of data", downloadData.length);
NSData *decoded_EncryptedData = [downloadData base64EncodedDataWithOptions:0];
NSString *decoded_EncryptedString = [[NSString alloc] initWithData: decoded_EncryptedData encoding:NSUTF8StringEncoding];
const void *key = #"0000000000000000000000000000000"; // key of length 32 char -> i know standard format for AES128 encryption is 16, maybe this requires 256 AES decryption
const void *iv = (__bridge const void *)([decoded_EncryptedString substringWithRange:NSMakeRange(0,16)]);
NSString *encryptedString = [decoded_EncryptedString substringWithRange:NSMakeRange(16, decoded_EncryptedString.length-16)];
// Now I have no idea what needs to happen, but from online research I found it should be something like this:
NSData encryptedData = [encryptedString dataUsingEncoding:NSUTF8StringEncoding]; // Writing it back into a data file
// Find size of returned data
size_t Size = encryptedData.length + kCCBlockSizeAES128;
// Initialise returned data
NSMutableData *decryptedData = [NSMutableData dataWithLength:Size];
// allocate variable to numBytesDecrypted
size_t numBytesDecrypted;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 0, KCCKeySizeAES128, iv,
[encryptedData bytes], [encryptedData length], [decryptedData bytes], [decryptedData length],
&numBytesDecrypted);
// Now I test whether the decryption process was successful:
if (cryptStatus == kCCSuccess) {
NSLog(#"Successfully decrypted);
NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding: NSUTF8StringEncoding];
}
}
The above code does display Successfully decrypted, however the string return null and size 0. Could someone please help me solve this? I would be so grateful.
Kind regards,
Lennaert
You have many problems.
You really need to know if the encryption is AES128 or AES256.
Encryption is data based, not string based. The conversion to a string decoded_EncryptedString is incorrect not should not be done.
The key is an issue, using a string is generally a bad idea, it is expected to be data bytes. Possibly the key is specified in hex so 32 hex characters would be 128 bits. If so conversion to data will be required.
'iv' and encryptedString are strings but they should be data, this a result of 2 above.
The key is not passed to CCCrypt.
Padding is generally used since the data is rarely exactly a block size in length, you probably need to specify PKCS7 padding to CCCrypt. You need to know if padding was used and if so was it PKCS7, php for example uses non-standard padding.
If PKCS7 padding is used the result must be trimmed to the length based on the variable numBytesDecrypted. If some other padding is used that must be trimmed.
If you want more help please supply test data and the result.
Finally, try and check back more frequently.

Have Cipher java in Objective-c?

I want to decrypt and encrypt a data using AES/CBC/PKCS5Padding in IOS,
in android i can use Cipher class to do it, but in IOS dont have those class to use it, right?
Currently i using this to do it, but it seem incorrect.
- (NSData *) DecryptAES: (NSString *) key{
char keyPtr[kCCKeySizeAES128];
bzero( keyPtr, sizeof(keyPtr) );
[key getCString: keyPtr maxLength: sizeof(keyPtr) encoding: NSUTF8StringEncoding];
size_t numBytesEncrypted = 0;
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer_decrypt = malloc(bufferSize);
const unsigned char iv[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
CCCryptorStatus result = CCCrypt( kCCDecrypt , kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
iv,
[self bytes], [self length],
buffer_decrypt, bufferSize,
&numBytesEncrypted );
if( result == kCCSuccess )
return [NSData dataWithBytesNoCopy:buffer_decrypt length:numBytesEncrypted];
return nil;}
how do i suppose to do it same like java did?
i have tried a lot diff way to do it, but it still now working, hope you guys can help me,
Thank's.
Additional information:
return data:
{"data":"3557793957617431633179755554443638483834686662707a652b7977454c655a654d344e316463513348324e2f2f6e6e4f54783961564e5a4f56426c6e69675a3850644c66734136446f736950516279366b375a5066302f7a424e654b47454c4153547132354c6746724e38432b4d7a3750514c4b3836796f7a54307764614666574e776373716d49766f517552347877766432337778584a796a49457878374e6c354a4f32434755583034722b4770324c79514658704d686e51586553574c6b6939303045754c6a7954494c454977493242796365496a75394b4a2b456347526136527244682b316168533067303651597a6b47713469717a75764d7856"}
encrypt and decrypt step
Cipher: AES (Rijndael block size = 128)
Key: fTG90HGFyeal3kGw
Mode: CBC
IV: CBC random (must append to crypted data)
*base64 is being used in order to make data transmission possible.
Request steps:
1- Collect required data in key-value format
2- JSON encode the collection
3- Encrypt JSON string
4- Generate random IV and append to head of encrypted data
5- Encode crypted data with base64
6- Post 5th item result under a key named “data”
Response steps:
1- Decode JSON string response
2- Decode the value of key named “data” with base64
3- Substring IV from decoded data
4- Decrypt the data
5- JSON decode the result of 4th item
6- Response in key-value format is
I follow the decrypt step to decrypt, i still not able to decrypt data.

Objective C: AES 256 Encryption with NSData Key

Previously I did Triple DES encryption to encrypt some data using a string key file, by defining a method
+ (NSData *)tripleDESEncryptWithKey:(NSString *)key dataToEncrypt:(NSData*)convertedData {}.
Now, similarly I am doing AES 256 encryption. But this time, I can not use a string as the key. I need to get NSData from a file in resources using
NSData *keyData = [NSData dataWithContentsOfFile:keyPath];
As I need to pass this key as parameter, I tried to convert it into string with
NSString *key = [[NSString alloc] initWithData:keyData encoding:NSUTF8StringEncoding];
but it returned NULL. So, How to use the Data key for AES 256 encryption ?
EDIT: I got that I should not use UTF8 encoding as the data file was made by Base64 encoding of a string. So Now the question is, how to get the string key using Base64 from keyData ?
If key variable returned NULL. Try to use like this.
NSString* key = [NSString stringWithUTF8String:[keyData bytes]];
Refer to KennyTM's Answer
UPDATE 1: You can also read the string directly from your file without convert in NSData
By NSFileHandle:
NSString * path = #"your key file path";
NSFileHandle * fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
NSData * buffer = nil;
while ((buffer = [fileHandle readDataOfLength:1024])) {
//do something with buffer
}
or use NSString
NSString * key = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
Refer to Dave DeLong's Answer
Note: Ensure your keyPath variable , Is it correct in the format of full or relative path?
UPDATE 2: You can also deal with Base64 Encoding with Matt Gallagher NSData+Base64 Class&Header (See also his blog there)
For encode base64
NSString * key = [[path dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString];
Hope it helps you!
Read the file:
NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath];
Then use one of the implementations in this post:
Base64 encoding options on the Mac and iPhone
to do your Base64 conversion.
Note: simply sticking your decryption key into a file is a bad idea. Optimally, the key would be stored securely by being encrypted by the user's own key.

Objective C: AES 256 Encryption with NSData Keyvalue

I want to do AES 256 encryption with a NSDATA Key. But everywhere I am finding example with NSString key. Now, how to use NSData key ?
You cannot use bytes as key. You have to use a string as key. Although, you can convert NSData bytes into a string. But note that the data has to be encoding with some valid string encoding.
Then you can use the following method to convert your NSData to a string , to use as a key.
NSString* newStr = [[[NSString alloc] initWithData:theData
encoding:NSUTF8StringEncoding] autorelease];

PBKDF2 using CommonCrypto on iOS

I'm trying to use CommonCrypto to generate keys using PBKDF2 but I can't seem to import CommonCrypto/CommonKeyDerivation.h, I just errors that it is not found.
Any ideas?
edit: I should probably mention I have already added the security framework and I can import all of the other CommonCrypto headers.
Here's how i generate AES256 keys. The only interesting this is that i get CommonCrypto to estimate for me how many rounds to use. It seems pretty straightforwards.
#import <CommonCrypto/CommonKeyDerivation.h>
...
// Makes a random 256-bit salt
- (NSData*)generateSalt256 {
unsigned char salt[32];
for (int i=0; i<32; i++) {
salt[i] = (unsigned char)arc4random();
}
return [NSData dataWithBytes:salt length:32];
}
...
// Make keys!
NSString* myPass = #"MyPassword1234";
NSData* myPassData = [myPass dataUsingEncoding:NSUTF8StringEncoding];
NSData* salt = [self generateSalt256];
// How many rounds to use so that it takes 0.1s ?
int rounds = CCCalibratePBKDF(kCCPBKDF2, myPassData.length, salt.length, kCCPRFHmacAlgSHA256, 32, 100);
// Open CommonKeyDerivation.h for help
unsigned char key[32];
CCKeyDerivationPBKDF(kCCPBKDF2, myPassData.bytes, myPassData.length, salt.bytes, salt.length, kCCPRFHmacAlgSHA256, rounds, key, 32);
Add this library to your project libcommonCrypto.dylib
#import into hash key generation class.
use following code to generate hash key.
This is the code what i have used:
// Salt data getting from salt string.
NSData *saltData = [#"Salt String" dataUsingEncoding:NSUTF8StringEncoding];
// Data of String to generate Hash key(hexa decimal string).
NSData *passwordData = [#"Hash key generated string" dataUsingEncoding:NSUTF8StringEncoding];
// Hash key (hexa decimal) string data length.
NSMutableData *hashKeyData = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH];
// Key Derivation using PBKDF2 algorithm.
int result = CCKeyDerivationPBKDF(kCCPBKDF2, passwordData.bytes, passwordData.length, saltData.bytes, saltData.length, kCCPRFHmacAlgSHA1, 1000, hashKeyData.mutableBytes, hashKeyData.length);
// Hexa decimal or hash key string from hash key data.
NSString *hexDecimalString = hashKeyData.description;
NSLog(#"Hexa decimal string:%#", hexDecimalString);
Are you building for iOS5 ? or earlier versions ?
Both API, CCKeyDerivationPBKDF and CCCalibratePBKDF, defined in the header file are only available on IOS5 (or OSX 10.7) and later.
You can make sure the file exists by executing this inside a terminal window:
$ find /Developer/ -name CommonKeyDerivation.h
/Developer//Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/include/CommonCrypto/CommonKeyDerivation.h
/Developer//Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/include/CommonCrypto/CommonKeyDerivation.h
/Developer//SDKs/MacOSX10.7.sdk/usr/include/CommonCrypto/CommonKeyDerivation.h