Encrypt/decrypt string with des cbc mode obj-c - objective-c

hi guys i'm pretty new in obj-c world and i would like know how can I encrypt a string in des? I already tried search but could not find any sample code that could help me the only thing I realized is that there is a class commonCrypt to do what I want but I do not know how to use it
my code
NSString* key = #"abc43HU0";
NSString *token = #"hellohello";
const void *vplainText;
size_t plainTextBufferSize;
plainTextBufferSize = [token length];
vplainText = (const void *) [token UTF8String];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t *movedBytes = NULL;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));
//NSString *initVec = #"init Vec";
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [key UTF8String];
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCModeCBC,
vkey, //"123456789012345678901234", //key
kCCKeySizeDES,
vinitVec,// vinitVec, //"init Vec", //iv,
vplainText, //"Your Name", //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
movedBytes);
NSString *result;
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64encoding;
crypt_result.text = myData;

this is the working code:
NSString* key = #"abc43HU0";
NSString *token = #"hellohello";
const void *vplainText;
size_t plainTextBufferSize = [token length];
vplainText = (const void *) [token UTF8String];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
Byte iv [] = {0x65, 0x110, 0x68, 0x26, 0x69, 0x178, 0x200, 0x219};
const void *vkey = (const void *) [key UTF8String];
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
vkey,
kCCKeySizeDES,
iv,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
NSString* result = [base64 base64EncodeData:myData];//my own method to encoding with base64

Try kCCOptionPKCS7Padding | kCCModeCBC for ccOptions parameter.

Related

About 3DES encryption / TripleDES different result in Objective-C and vb

Now there is a demand, let me change the VB program of win to Mac cocoa program.
There is a 3DES encryption problem that bothers me
The encrypted strings of Mac and vb are completely different.
VB uses the TripleDES library, but Mac cannot import this library. I had to write one myself, but the results were different.
Mac:Objective-C,
Win:vb
I will upload my program, please help me. Thank you
//obj code
- (NSString*)doEncryptStr:(NSString*)originalStr { //withKey:(NSString*)key
NSString *key = #"XXXX";
uint8_t keyByte[kSecrectKeyLength];
//NSMutableData *keyData = [[NSMutableData alloc] init];
int i;
for (i=0; i < [key length]/2; i++) {
NSString *tempNumber = [key substringWithRange: NSMakeRange(i * 2, 2)];
//NSLog(#"tempNum == %#", tempNumber);
NSScanner *scanner = [NSScanner scannerWithString:tempNumber];
//NSLog(#"scanner == %#", scanner.string);
unsigned int temp;
[scanner scanHexInt:&temp];
Byte B = (Byte)(0xFF & temp);
keyByte[i] = B;
}
//NSUTF8StringEncoding
NSData* data = [originalStr dataUsingEncoding:NSUTF16StringEncoding];
size_t plainTextBufferSize = [data length];
const void *vplainText = (const void *)[data bytes];
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 void *vkey = (const void *) keyByte;
const void *vinitVec = (const void *) [gIv UTF8String];
ccStatus = CCCrypt(
kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
vkey,
kCCKeySizeDES,
vinitVec,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
NSString *result = [GTMBase64 stringByEncodingData:myData];
NSLog(#"result == %#",result);
return result;
}
Below is the vb code
Public Function EncryptData(ByVal plaintext As String) As String
' Convert the plaintext string to a byte array.
Dim plaintextBytes() As Byte = _
System.Text.Encoding.Unicode.GetBytes(plaintext)
' Create the stream.
Dim ms As New System.IO.MemoryStream
' Create the encoder to write to the stream.
Dim encStream As New CryptoStream(ms, _
TripleDes.CreateEncryptor(), _
System.Security.Cryptography.CryptoStreamMode.Write)
' Use the crypto stream to write the byte array to the stream.
encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
encStream.FlushFinalBlock()
' Convert the encrypted stream to a printable string.
Return Convert.ToBase64String(ms.ToArray)
End Function

How to get IV from AES encryption in objective C?

I am new to AES encryption.
I am using following java code for encrypting my password and it works fine.
private void startEncryption() throws UnsupportedEncodingException {
String text = "15";
String key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String ivString = "LXUJOLKDEJKGTMAV";
byte[] valueBytes = text.getBytes();
byte[] keyBytes = keyString.getBytes("UTF-8");
byte[] ivBytes = ivString.getBytes();
byte[] ivFinalBytes = new byte[16];
for(int i=0; i<16; i++){
ivFinalBytes[i] = ivBytes[i];
}
encrypt(valueBytes, keyBytes, ivFinalBytes);
}
private void encrypt(byte[] valueBytes, byte[] keyBytes, byte[] ivBytes) {
try {
SecretKeySpec ks = new SecretKeySpec(keyBytes, "AES");
Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
c.init(Cipher.ENCRYPT_MODE, ks, ivParameterSpec);
byte[] clearText = c.doFinal(valueBytes);
String ivPass = Base64.encodeToString(c.getIV(), Base64.DEFAULT);
String pass = Base64.encodeToString(clearText, Base64.DEFAULT);
encryptedPassword = ivPass+pass;
encryptedPassword = encryptedPassword.replace("\n", "").replace("\r", "");
} catch (Exception e) {
System.out.println("exception: "+e);
}
}
Output looks like following:
azhTMrwGqTN21O4oRenR6Q==VE5LTU9GT1BCWldRSEREQQ==
Now I am trying to do same thing in objective C. Following is the code which i am using right now:
-(NSString*)testActuallyEncrypting:(NSString *)data
{
NSString *key = #"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
NSString *iv = #"LXUJOLKDEJKGTMAV";
NSData *dataIn = [data dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding];
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0;
NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
ccStatus = CCCrypt( kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyData.bytes, kCCKeySizeAES256,
ivData.bytes,
dataIn.bytes, dataIn.length,
dataOut.mutableBytes, dataOut.length,
&cryptBytes);
if (ccStatus != kCCSuccess) {
NSLog(#"CCCrypt status: %d", ccStatus);
}
dataOut.length = cryptBytes;
NSString *objcEncrypted = [dataOut base64EncodedStringWithOptions:0];
NSLog(#"objcEncrypted: %#", objcEncrypted);
return objcEncrypted;
}
Seems like I am getting the right encrypted password.
VE5LTU9GT1BCWldRSEREQQ==
How can I get IV which should be like azhTMrwGqTN21O4oRenR6Q==?
I figured it out and adding following line of codes solved my problem:
NSString *ivEncrypted = [ivData base64EncodedStringWithOptions:0];
NSString *encryptedString = [NSString stringWithFormat:#"%#%#", ivEncrypted, objcEncrypted];
and then return encryptedString

Equal Objective C result for java Cipher.getInstance("DESede/ECB/NoPadding")

Java code is done to generate 3DES result, segment code as below:
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result = cipher.doFinal(data);
Now, I need to implement same result in objective-C, below is my try, but the result is not even close.
+(NSString *) try3DES:(NSString *)plainText key:(NSString *)key
{
NSString *ciphertext = nil;
NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger dataLength = [textData length];
unsigned char buffer[1024];
memset(buffer, 0, sizeof(char));
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
[key UTF8String],
kCCKeySizeDES,
nil,
[textData bytes],
dataLength,
buffer,
1024,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
ciphertext = [self convertDataToHexStr:data];
}
return ciphertext;
}
Could anybody can help?

encrypt nsstring with 3des ios7

I am new with iOS7 development and objective c, and i need to develop an application which will send encrypted data with 3DES to a server,I have searched in stack overflow and Net but still unable to get it work, finally i tried this code but i got null as result,
+ (NSString*)encrypt:(NSString*)plainText withKey:(NSString*)key{
uint8_t keyByte[kSecrectKeyLength];
NSMutableData *keyData = [[NSMutableData alloc] init];
int i;
for (i=0; i < [key length] / 2; i++) {
NSString *tempNumber = [key substringWithRange: NSMakeRange(i * 2, 2)];
NSScanner *scanner=[NSScanner scannerWithString:tempNumber];
unsigned int temp;
[scanner scanHexInt:&temp];
Byte B = (Byte)(0xFF & temp);
keyByte[i] = B;
}
NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
size_t plainTextBufferSize = [data length];
const void *vplainText = (const void *)[data bytes];
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 void *vkey = (const void *) keyByte;
const void *vinitVec = (const void *) [gIv UTF8String];
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
//NSString *result = [GTMBase64 stringByEncodingData:myData];
NSString *result = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
NSLog(#"result=%#",result);
return result;
}
Please have u any idea about the solution???
lol i just struggled with this myself the other day, i have a working solution now using this code
+ (NSData *)tripleDesEncryptString:(NSString *)input
key:(NSString *)key
error:(NSError **)error
{
NSParameterAssert(input);
NSParameterAssert(key);
NSData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
size_t outLength;
NSAssert(keyData.length == kCCKeySize3DES, #"the keyData is an invalid size");
NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length + kCCBlockSize3DES)];
CCCryptorStatus
result = CCCrypt(kCCEncrypt, // operation
kCCAlgorithm3DES, // Algorithm
kCCOptionPKCS7Padding | kCCOptionECBMode, // options
keyData.bytes, // key
keyData.length, // keylength
nil,// iv
inputData.bytes, // dataIn
inputData.length, // dataInLength,
outputData.mutableBytes, // dataOut
outputData.length, // dataOutAvailable
&outLength); // dataOutMoved
if (result != kCCSuccess) {
if (error != NULL) {
*error = [NSError errorWithDomain:#"com.your_domain.your_project_name.your_class_name."
code:result
userInfo:nil];
}
return nil;
}
[outputData setLength:outLength];
return outputData;
}
+ (NSString *)tripleDesDecryptData:(NSData *)input
key:(NSString *)key
error:(NSError **)error
{
NSParameterAssert(input);
NSParameterAssert(key);
NSData *inputData = input;
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
size_t outLength;
NSAssert(keyData.length == kCCKeySize3DES, #"the keyData is an invalid size");
NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length + kCCBlockSize3DES)];
CCCryptorStatus
result = CCCrypt(kCCDecrypt, // operation
kCCAlgorithm3DES, // Algorithm
kCCOptionPKCS7Padding | kCCOptionECBMode, // options
keyData.bytes, // key
keyData.length, // keylength
nil,// iv
inputData.bytes, // dataIn
inputData.length, // dataInLength,
outputData.mutableBytes, // dataOut
outputData.length, // dataOutAvailable
&outLength); // dataOutMoved
if (result != kCCSuccess) {
if (error != NULL) {
*error = [NSError errorWithDomain:#"com.your_domain.your_project_name.your_class_name."
code:result
userInfo:nil];
}
return nil;
}
[outputData setLength:outLength];
return [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];
}
you probably want to base64 encode the data the comes out of the encryption method, and then un-base64 anything that you want to decrypt as well, there are built in methods for NSData to do this now, eg:
[data base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)];
to test if the functions work, i used this test function
+ (void) testEncryptionAndDecryption {
NSData *encrypted = [self tripleDesEncryptString:#"test" key:#"123456789123456789123456" error:nil];
NSLog(#"encrypted data length: %lu", (unsigned long)encrypted.length);
NSString *decrypted = [self tripleDesDecryptData:encrypted key:#"123456789123456789123456" error:nil];
NSLog(#"decrypted text: %#", decrypted);
}
this gave me the correct output that you would expect

uint8_t[] array transform to NSString got (null)

I have no idea why the (char *)uint8_t array transform to NSString doesn't work.
ivString always is (null)
- (IBAction)encryptPacketBtnTouchDown:(id)sender {
NSString *key = #"1234567890123456";
NSData *plain = [plainMessage.text dataUsingEncoding:NSUTF8StringEncoding];
uint8_t initialisationVector[16];
arc4random_buf(initialisationVector, 16);
NSString* ivString = [NSString stringWithUTF8String:(char *)initialisationVector];
NSData *cipherData = [plain AES128EncryptWithKey:key iv:ivString];
[asyncSocket writeData:cipherData withTimeout:-1.0 tag:0];
NSString* cipherString = [[NSString alloc] initWithBytes:[cipherData bytes]
length:[cipherData length]
encoding:NSASCIIStringEncoding];
}
cipherData NSData * 0x1edaf3a0 16 bytes
cipherString NSString * 0x00000000
initialisationVector uint8_t [16]
ivString NSString * 0x00000000
key NSString * 0x000d28c4 #"1234567890123456"
plain NSData * 0x1ed80760 9 bytes
P.S.
NSString* ivString = [[NSString alloc] initWithBytes:initialisationVector
length:16
encoding:NSUTF8StringEncoding];
This also won't works. Still got (null)
The method I am calling is :
- (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv
{
char keyPtr[kCCKeySizeAES128 + 1];
memset(keyPtr, 0, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCBlockSizeAES128 + 1];
memset(ivPtr, 0, sizeof(ivPtr));
[iv getCString:ivPtr
maxLength:sizeof(ivPtr)
encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesCrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(operation,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[self bytes],
dataLength,
buffer,
bufferSize,
&numBytesCrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
}
free(buffer);
return nil;
}
- (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv
{
return [self AES128Operation:kCCEncrypt key:key iv:iv];
}
Finally, I got the answer!
I just need treat the uint8_t[] array as a char[] array. Then, transform the char[] array to NSString by below line:
NSString* ivString = [NSString stringWithCString:initialisationVector encoding:NSASCIIStringEncoding];
Result is:
ivString NSString * 0x1d8489c0 #"¹U ¡hÌTÖÆáβÍ"