Rishabh Tayal
Rishabh Tayal

Reputation: 496

3DES encryption with CBC mode in objective c

I am trying to encrypt a NSString using 3DES with CBC mode encryption on iOS.

Same encryption method is being used on ASP.NET as well and the encrypted string they are getting works with the webservice. The encrypted string for woodcraft554 obtained from .NET code is: 9SWzd+rlvu/tK5UZoCXt8Q==.

.NET is using zero padding for encrytion. The code I am using is:

+(NSString*)new3DESwithoperand:(NSString*)plaintext encryptOrDecrypt:(CCOperation)encryptorDecrypt key:(NSString*)key initVec:(NSString*)initVec
{     

NSData* data = [plaintext dataUsingEncoding:NSUTF8StringEncoding];
const void *vplainText = [data bytes];;
size_t plainTextBufferSize = [data length];
NSLog(@"%@, Length: %u",[data description],[data length]);

size_t bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
NSLog(@"%zu, sizof of uint8_t: %zu",bufferPtrSize, sizeof(uint8_t));
size_t movedBytes = 0;
uint8_t *bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
NSLog(@"%zu",sizeof(bufferPtr));
memset((void*)bufferPtr, 0x0, bufferPtrSize);
NSLog(@"%zu",sizeof(bufferPtr));
//    memset((void *)initVec, 0x0, (size_t) sizeof(initVec));
const void * vkey = [[NSString base64DataFromString:key] bytes];
const void *vinitVec = [[NSString base64DataFromString:initVec] bytes];
NSLog(@"vinitvec: %@",[[NSString base64DataFromString:initVec] description]);

CCCryptorStatus ccStatus;
ccStatus = CCCrypt(encryptorDecrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding & kCCModeCBC,
                   vkey,
                   kCCKeySize3DES,
                   vinitVec,
                   vplainText,
                   plainTextBufferSize,
                   (void*)bufferPtr,
                   bufferPtrSize,
                   &movedBytes);

NSData* result = [NSData dataWithBytes:(const void*)bufferPtr length:(NSUInteger)movedBytes];
NSString* str = [NSString base64StringFromData:result length:result.length];
NSLog(@"%@",str);

return str;
}

I have compared vplainText, vkey and vinitVec from objective-c code to that in .NET. They are same. The encrypted string I am getting is 9SWzd+rlvu8=. I believe it's something to do with padding.

Here is equivalent .NET code they are using:

protected string EncryptCreditCard(string creditCard)
{
    try
    {
        string ENCRYPTION_KEY = ConfigurationManager.AppSettings["ENCRYPTION_KEY"].ToString();
        string ENCRYPTION_IV = ConfigurationManager.AppSettings["ENCRYPTION_IV"].ToString();

        SymmetricAlgorithm sa = SymmetricAlgorithm.Create("TripleDES");
        sa.Key =   System.Convert.FromBase64String(ENCRYPTION_KEY);
        sa.IV =  System.Convert.FromBase64String(ENCRYPTION_IV);
        sa.Padding = PaddingMode.Zeros;

        byte[] inputByteArray = Encoding.ASCII.GetBytes(creditCard);
        MemoryStream mS = new MemoryStream();

        ICryptoTransform trans = sa.CreateEncryptor();
        byte[] buf = new byte[2048];
        CryptoStream cs = new CryptoStream(mS, trans, CryptoStreamMode.Write);
        cs.Write(inputByteArray, 0, inputByteArray.Length);
        cs.FlushFinalBlock();

        return Convert.ToBase64String(mS.ToArray());
    }
    catch
    {
        return "";
    }
}

How can I get a correct encrypted string in iOS ?

Upvotes: 2

Views: 4220

Answers (2)

Jugal Desai
Jugal Desai

Reputation: 164

The issue is with "key" which is used for encryption. iOS uses a 24Byte key while Adnroid and .NET use 16Byte key.

Have posted a detailed solution for the same issue, which depicts key generation. Solution for different encryption value generated in iOS

Upvotes: 0

Maarten Bodewes
Maarten Bodewes

Reputation: 94058

By using zero padding. Your code clearly states kCCOptionPKCS7Padding, which is not zero padding. The cipher text seems identical otherwise.

Note that you are better off using PaddingMode.PKCS7 in your .NET code. It adds some data in the odd case that your plain text is already a number of times the block size in size, but it is standardized and unpadding is not depending on the plain text value anymore.

Upvotes: 1

Related Questions