Reputation: 152
im trying to implement an encryption way on iOS . to match the one running on JAVA .
but every thing i tried result in a different encrypted schema
here is my Java Code that i Use for Encryption :
public static String encrypt(String plaintext)
throws Exception
{
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sharedkey, "DESede"), new IvParameterSpec(sharedvector));
byte[] encrypted = c.doFinal(plaintext.getBytes("UTF-8"));
return Base64.encode(encrypted);
}
is there any easy way to use DESede/CBC/PKCS5Padding in objective c ?
this is the code I'm Using but it gives different result
+ (NSString*) doCipher:(NSString*)plainText:(CCOperation)encryptOrDecrypt {
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt)
{
// NSData *EncryptData = [NSData dataWithBase64EncodedString:plainText];
// plainTextBufferSize = [EncryptData length];
// vplainText = [EncryptData bytes];
}
else
{
NSData *tempData = [plainText dataUsingEncoding:NSASCIIStringEncoding];
plainTextBufferSize = [tempData length];
vplainText = [tempData bytes];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t ivkCCBlockSize3DES;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
//my shared key i changed to Zeros
NSMutableData *payload = [[NSMutableData alloc] init];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
[payload appendBytes:"00" length:1];
NSString *key = [[NSString alloc]initWithData:payload encoding:NSUTF8StringEncoding];
//my iV i changed it to zeros
NSMutableData *IV = [[NSMutableData alloc] init];
[IV appendBytes:"00" length:1];
[IV appendBytes:"00" length:1];
[IV appendBytes:"00" length:1];
[IV appendBytes:"00" length:1];
[IV appendBytes:"00" length:1];
[IV appendBytes:"00" length:1];
[IV appendBytes:"00" length:1];
[IV appendBytes:"00" length:1];
NSLog(@"key byte is %s", [payload bytes]);
NSLog(@"IV byte is %s", [IV bytes]);
// Initialization vector; dummy in this case 0's.
uint8_t iv[kCCBlockSize3DES];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
(const void *)[payload bytes], //"123456789012345678901234", //key
kCCKeySize3DES,
[IV bytes], //iv,
vplainText, //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
//if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
/*else*/ if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";
NSString *result;
if (encryptOrDecrypt == kCCDecrypt)
{
// result = [[NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:[(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding]];
result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
NSLog(@"data is: %@", myData);
result = [myData base64EncodedString];
// result = [[NSString alloc]initWithData:myData encoding:NSUTF8StringEncoding];
}
return result;
}
Upvotes: 3
Views: 4245
Reputation: 2585
Updating Waleed's Answer
key and IV could be :
const unsigned char *keyString = (const unsigned char *)[@"ASAF#Key$M0BiLE!WS@DG_1@" cStringUsingEncoding: NSUTF8StringEncoding];
const unsigned char *initializeVactorString = (const unsigned char *)[@"ASAF@DG#" cStringUsingEncoding: NSUTF8StringEncoding];
Complete method would be :
- (NSString*) EncodeText:(NSString*)plainText enc:(CCOperation)encryptOrDecrypt{
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt)
{
NSString *base64EncodedString = [[plainText dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
NSData *encryptData = [[NSData alloc]initWithBase64EncodedString:base64EncodedString options:0];
plainTextBufferSize = [encryptData length];
vplainText = [encryptData bytes];
}
else
{
plainTextBufferSize = [plainText length];
vplainText = (const void *) [plainText UTF8String];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
const unsigned char *keyString = (const unsigned char *)[@"ASAF#Key$M0BiLE!WS@DG_1@" cStringUsingEncoding: NSUTF8StringEncoding];
const unsigned char *initializeVactorString = (const unsigned char *)[@"ASAF@DG#" cStringUsingEncoding: NSUTF8StringEncoding];
uint8_t iv[kCCBlockSize3DES];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
keyString,
kCCKeySize3DES,
initializeVactorString,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
else{
if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";
}
NSString *result;
if (encryptOrDecrypt == kCCDecrypt)
{
result = [ [NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64EncodedStringWithOptions:0];
}
NSLog(@"%@",result);
return result ;
}
Some times server wants hex conversion, here is the way to convert string into hex
+ (NSString *) stringToHex:(NSString *)str{
NSUInteger len = [str length];
unichar *chars = malloc(len * sizeof(unichar));
[str getCharacters:chars];
NSMutableString *hexString = [[NSMutableString alloc] init];
for(NSUInteger i = 0; i < len; i++ )
{
[hexString appendString:[NSString stringWithFormat:@"%x", chars[i]]];
}
free(chars);
return hexString ;
}
+ (NSString *) stringFromHex:(NSString *)str{
NSMutableData *stringData = [[NSMutableData alloc] init];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i;
for (i=0; i < [str length] / 2; i++) {
byte_chars[0] = [str characterAtIndex:i*2];
byte_chars[1] = [str characterAtIndex:i*2+1];
whole_byte = strtol(byte_chars, NULL, 16);
[stringData appendBytes:&whole_byte length:1];
}
return [[NSString alloc] initWithData:stringData encoding:NSASCIIStringEncoding];
}
Upvotes: 1
Reputation: 152
@owlstead thanx for your hint ,
i really checked every thing and you are right the problem was with the input
so here is the right way to enter the input :
unsigned char result1[24]= {0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,00,00,00,00,0};
unsigned char IV3[8]={0,0,0,0,0,0,0,0};
off-course you have to change the numbers to your own key and IV .
the Full Code : just change the IV and the result to your data :)
- (NSString*) doCipher:(NSString*)plainText enc:(CCOperation)encryptOrDecrypt{
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt)
{
NSData *EncryptData =[NSData dataWithBase64EncodedString:plainText];
plainTextBufferSize = [EncryptData length];
vplainText = [EncryptData bytes];
}
else
{
plainTextBufferSize = [plainText length];
vplainText = (const void *) [plainText UTF8String];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t ivkCCBlockSize3DES;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
unsigned char result1[24]= {0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,00,00,00,00,0};
unsigned char IV3[8]={0,0,0,0,0,0,0,0};
uint8_t iv[kCCBlockSize3DES];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding ,
result1, //"123456789012345678901234", //key
kCCKeySize3DES,
IV3 , //iv,
vplainText, //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
//if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
/*else*/ if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";
NSString *result;
if (encryptOrDecrypt == kCCDecrypt)
{
result = [ [NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
NSLog(@"data is: %@", myData);
result = [NSData base64StringFromData:myData length:myData.length];
// result = [[NSString alloc]initWithData:myData encoding:NSUTF8StringEncoding];
}
return result;
}
Upvotes: 3