2014-02-20 4 views
7

Я пытаюсь преобразовать код, написанный на C#, в объектив c, я попытался, но не смог получить тот же результат. Любая помощь будет заметна.Код C# для Objective C Эквивалентный код

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; 
    }   
} 

выше код используется для encrytion. Я попытался получить эквивалентные функции в объекте для RFC2898derivebytes.

Objective C код, который я пробовал:

-(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]; 
} 
+1

Хороший вопрос !! – ManiaChamp

+0

@ManishSharma Очень хорошо поставлен, и я тоже не вижу слишком плохого в коде - за исключением, конечно, того, что я делаю в своем ответе. –

ответ

1

Эй, если вы хотите попробовать несколько фраз и decrytion как в ios, так и в C#, вы можете использовать код, указанный по этой ссылке. Меня устраивает. Я нашел this link

+1

Спасибо за ответ, Маниш, но не могли бы вы дать намек на то, что выполняется в ссылке в ответе (как минимум?). Просто предоставление ссылки не считается ответом в политике SO. Кроме того, первый ответ на сайте stackoverflow имеет +15 (+14 к настоящему времени), но содержит небезопасный код. Прокомментировал это в ответе. С шифрованием вы не можете просто иметь * рабочий * код, он также должен быть криптографическим. –

+0

@owlstead: В этой ссылке он не использует RFC2898Derivebytes для генерации ключа шифрования, используя соль в dotnet. Поэтому нам не нужно найти какой-либо эквивалентный метод в объективе c. Он просто использует AES-encrypion. Вы можете загрузить файл zip-файла по ссылке выше, которая содержит как dotnhet, так и объектный код c. – ManiaChamp

+0

Да, в этом дело. Я добавил комментарий к SO, к которому они ссылаются: http://stackoverflow.com/a/539928/589259. Я не хотел создавать учетную запись на других страницах блога ребят. –

4

Проблема вы столкнулись в том, что вызов функции PBKDF2 раз и извлечения первых 32 байт, а затем 16 байт из не то же самое, как вызов он дважды и извлекает 32 байта и 16 байтов из отдельных вызовов функций. В настоящее время вы, вероятно, увидите, что первые 16 байтов ключа и первые 16 байтов IV идентичны (поскольку PBKDF2 детерминирован после установления параметров).

Что должно работать, запрашивает 32 + 16 = 48 байт, а затем извлекает первые 32 байта в качестве ключа и следующие 16 байтов как IV.

Еще лучше - но сложнее реализовать - опция заключается в использовании KBKDF (Key Based Функция деривации ключа) на результат PBKDF2. Проблема в том, что PBKDF2 внутренне вызывается трижды для создания 48 байтов (потому что SHA-1 имеет выходной размер 20 байтов). Это означает, что вам нужно сделать три вызова - включая все итерации - в то время как злоумышленнику, вероятно, нужно сделать только одну или две вызовы.

+0

Спасибо, что ответили кратко. – maddy110989

+0

Спасибо большое Маартен ... Вы спасли мой день ... С 32 + 16 = 48 байт для расчета IV. –

0

Мне не удалось найти полный пример, основанный на реализации .Net, упомянутый в вопросе ... Итак, вот решение/код, который работал на меня. (Обратите внимание: не забудьте заменить соль и пароль)

Примечание: Для того, чтобы избежать шаблонного кода я использовал 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]; 

Я надеюсь, что помогает кому-то получить в ответ быстрее.

Смежные вопросы