Encrypting data in php on server side and decrypting in iOS fails.
On server in php it looks like this(just for test):
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, "a16byteslongkey!a16byteslongkey!", "iphone", MCRYPT_MODE_CBC, $iv);
$base64encoded_ciphertext = base64_encode($ciphertext);
return $base64encoded_ciphertext;
In iOS:
NSData *decrypted = [[RNCryptor AES256Cryptor] decryptData:[QSStrings decodeBase64WithString: text] password:@"a16byteslongkey!a16byteslongkey!" error:&error];
NSLog(@"errro - %@", [error description]);
NSString *decryptedString = [[[NSString alloc] initWithData: decrypted encoding: NSUTF8StringEncoding] autorelease];
Error description is:
Error Domain=net.robnapier.RNCryptManager Code=2 "Unknown header" UserInfo=0x8582e10 {NSLocalizedDescription=Unknown header}
Using RNCryptor: https://github.com/rnapier/RNCryptor
in encryptor that is the place where error is thrown:
if (![header isEqualToData:[NSData dataWithBytes:AES128CryptorHeader length:sizeof(AES128CryptorHeader)]]) {
*error = [NSError errorWithDomain:kRNCryptorErrorDomain code:kRNCryptorUnknownHeader
userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"Unknown header", @"Unknown header") forKey:NSLocalizedDescriptionKey]];
return NO;
}
What is wrong whith this?
Just reading the site for RNCryptor, I believe it is a full message input output encryptor. If you look at the data format on their wiki
https://github.com/rnapier/RNCryptor/wiki/Data-Format
I believe that they EXPECT that your data to ENCRYPT does NOT have a header, but if you are DECRYPTING, then it expects that the data was encrypted using their encryptor, which adds header and hmac.
If I'm correct, the data that your server side puts together is simply the cipher-text portion of the full message that RNCryptor expects to see!!!
//After getting data from server
-(Void)getDataFromServer:(NSData*)responseData
{
NSString *base64String = [responseData base64EncodedStringWithOptions:0];
//Decode base64 data
NSData *decodedData = [DatabaseHandler base64DataFromString:newStr];
NSData *decryptedData = [RNDecryptor decryptData:decodedData withSettings:kRNCryptorAES256Settings password:@"YourKey" error:&error];
NSLog(@"%@",[error userInfo]);
NSString *dataToDecrypt= [decryptedData base64EncodedStringWithOptions:0];
NSString* newStr = [[NSString alloc] initWithData:decryptedData
encoding:NSUTF8StringEncoding];
}
- (NSString *) base64StringFromData: (NSData *)data length: (int)length {
unsigned long ixtext, lentext;
long ctremaining;
unsigned char input[3], output[4];
short i, charsonline = 0, ctcopy;
const unsigned char *raw;
NSMutableString *result;
lentext = [data length];
if (lentext < 1)
return @"";
result = [NSMutableString stringWithCapacity: lentext];
raw = [data bytes];
ixtext = 0;
while (true) {
ctremaining = lentext - ixtext;
if (ctremaining <= 0)
break;
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext)
input[i] = raw[ix];
else
input[i] = 0;
}
output[0] = (input[0] & 0xFC) >> 2;
output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
output[3] = input[2] & 0x3F;
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++)
[result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
for (i = ctcopy; i < 4; i++)
[result appendString: @"="];
ixtext += 3;
charsonline += 4;
if ((length > 0) && (charsonline >= length))
charsonline = 0;
}
return result;
}
Did you follow php
and iOS
libraries from here:
My requirement was same. Encrypted data reached my iOS device and objective c has to decrypt it.
After pulling almost all my hairs today, I am able to make it now. Here is a snippet of code below:
NSString *message = @"AwF+ttZCyQ7eurRU2zo4KGqQTLBXRRdmBiYe65uv/3AENxUKf6wo3Cpsh8Yk7/OsOwXRDDR3lO5OKNwhJCSxxUNYbpBwWb2KDSxiRbG+11Vrfbk35VRvelAo2Ai8PAz4FJ9z9u7NdBvyVQYF8v1Pd7/rB4TMXaWd98AM4KO3EYmLhTxMpbqDu1LJXDT4TDgXsjv7/ISnISQK3oTmG1vYlO7N";
NSString *password = @"myPassword";
NSData *data = [[NSData alloc] initWithBase64EncodedString:message options:0];
NSError *error;
NSData *decryptedData = [RNDecryptor decryptData:data
withPassword:password
error:&error];
NSString* newStr = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
NSLog(@"\n\nerror: %@\n\nString:%@", error, newStr);
If you download and run encrypt.php
from their php
sample (inside RNCryptor-php-master > examples > encrypt.php
) you will receive that base64
string above ( NSString *message
). Its password is myPassword
there. And running this obj c
code will return you this👇
"Here is my test vector. It's not too long, but more than a block and needs padding."
This line 👆is right there is source code of encrypt.php
. The mistake I was doing was, I was converting NSString
to NSData
directly like below👇
NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
the decryption worked after I decoded that base64
string like below👇
NSData *data = [[NSData alloc] initWithBase64EncodedString:message options:0];
thats it. Hope it helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.