7

I am trying to convert code written in C# to objective c, I tried but unable to get the same result . Any help will be appreciable.

internal static class Common  {
    static string encryptionKey = "0C61L2FSL2F3E7X8E9T1L2F3E4O5";
    static byte[] salt = new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76};
         
    internal static string Encrypt(string clearText)
    {
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(encryptionKey, salt);

            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);

            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }
                clearText = Convert.ToBase64String(ms.ToArray());
            }
        }
        return clearText;
    }   
}   

Above Code is used for encrytion. I tried to get the equivalent functions in objective for RFC2898derivebytes.

Objective c code that i tried :

-(void)doEncryption {

    NSString *url = @"www.google.com";

    const char salt[] = {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76};

    NSData *saltData =[NSData dataWithBytes:salt length:13];

    NSData* myPassData = [EncryptionKey dataUsingEncoding:NSUTF8StringEncoding];


    unsigned char key[32];

    CCKeyDerivationPBKDF(kCCPBKDF2, myPassData.bytes, myPassData.length, saltData.bytes, saltData.length, kCCPRFHmacAlgSHA1, 1000, key, 32);

    unsigned char InitialVector[16];

    CCKeyDerivationPBKDF(kCCPBKDF2, myPassData.bytes, myPassData.length, saltData.bytes, saltData.length, kCCPRFHmacAlgSHA1, 1000, InitialVector, 16);


    NSString *Aeskey = [[NSString alloc] initWithBytes:key length:sizeof(key) encoding:NSUnicodeStringEncoding];
    NSLog(@"Key AES : %@",Aeskey);



    NSString *AesIV = [[NSString alloc] initWithBytes:InitialVector length:sizeof(key) encoding:NSASCIIStringEncoding];

    NSString *encryptedString =  [AESCrypt encrypt:url password:Aeskey  andIV:AesIV];


    [self doDecryption:encryptedString withKey:nil];
 }
maddy110989
  • 101
  • 5
  • @ManishSharma Very well put, and I don't see much wrong with the code either - except of course the point I'm making in my answer. – Maarten Bodewes Feb 20 '14 at 13:17

2 Answers2

4

The problem you are facing is that calling the PBKDF2 function once and extracting first 32 bytes, and then 16 bytes from is not the same as calling it twice, and extracting 32 bytes and 16 bytes from the separate function invocations. Currently you'll probably see that the first 16 bytes of the key and the first 16 bytes of the IV are identical (as PBKDF2 is deterministic once the parameters have been established).

What should work is asking for 32 + 16 = 48 bytes, then extracting the first 32 bytes as key and the next 16 bytes as IV.

An even better - but harder to implement - option is to use a KBKDF (Key Based Key Derivation Function) on the result of the PBKDF2. The problem is that the PBKDF2 internally is invoked thrice to create the 48 bytes (because SHA-1 has an output size of 20 bytes). This means that you have to do three invocations - including all the iterations - while an attacker probably only has to do one or two invocations.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
0

I didn't manage to find a complete example based on the .Net implementation mentioned in the question... So here's the solution/code that worked for me. (note: make sure to replace salt and password)

Note: In order to avoid boilerplate code I used https://github.com/kelp404/CocoaSecurity

const char salt[] = { 12, 33, 63, 74, 105, 116, 206, 72 };
NSString *password = @"password";

NSData* saltData = [NSData dataWithBytes:salt length:sizeof(salt)];
NSData* myPassData = [password dataUsingEncoding:NSUTF8StringEncoding];

unsigned char key[48];
CCKeyDerivationPBKDF(kCCPBKDF2, myPassData.bytes, myPassData.length, saltData.bytes, saltData.length, kCCPRFHmacAlgSHA1, 1000, key, 48);


NSData *AesKey = [NSData dataWithBytes:key length:32];
NSData *AesIV = [[NSData dataWithBytes:key length:48] subdataWithRange:NSMakeRange(32, 16)];

CocoaSecurityResult *result2 = [CocoaSecurity aesDecryptWithData:encrypted key:AesKey iv:AesIV];

I hope that helps someone else get to an answer faster.

rodrigoArantes
  • 354
  • 1
  • 4
  • 13