2013-04-01 2 views
1

Я пытаюсь зашифровать строку в Xcode и расшифровать ее с помощью PHP или зашифровать с помощью PHP и расшифровать с помощью Xcode.Xcode AES encrypt/decrypt - php compatibilty issues

Так что в первую очередь я пытаюсь получить тот же результат AES encryption.

Вот мой Xcode файл (я положил все в одном файле для простоты):

#import "t.h" 
#import <CommonCrypto/CommonCryptor.h> 

@interface NSData(AES) 
- (NSData*)AES256EncryptWithKey:(NSString*)key; 
- (NSData*)AES256DecryptWithKey:(NSString*)key; 
@end 

@implementation NSData (AES) 

- (NSData*)AES256EncryptWithKey:(NSString*)key { 
char keyPtr[kCCKeySizeAES256]; 

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding]; 

NSString *iv = @"1234567812345678"; 
char ivPtr[kCCKeySizeAES128]; 

[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSASCIIStringEncoding];  

NSUInteger dataLength = [self length]; 

size_t bufferSize   = dataLength + kCCBlockSizeAES128; 
void* buffer    = malloc(bufferSize); 

size_t numBytesEncrypted = 0; 
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, NULL, 
             keyPtr, kCCKeySizeAES256, 
             ivPtr /* initialization vector (optional) */, 
             [self bytes], dataLength, /* input */ 
             buffer, bufferSize, /* output */ 
             &numBytesEncrypted); 

if (cryptStatus == kCCSuccess) 
{ 
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
} 

free(buffer); //free the buffer; 
return nil; 
} 

- (NSData*)AES256DecryptWithKey:(NSString*)key { 
char keyPtr[kCCKeySizeAES256]; 

NSString *iv = @"1234567812345678"; 
char ivPtr[kCCKeySizeAES128]; 

[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSASCIIStringEncoding]; 


// fetch key data 
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding]; 

NSUInteger dataLength = [self length]; 

size_t bufferSize   = dataLength + kCCBlockSizeAES128; 
void* buffer    = malloc(bufferSize); 

size_t numBytesDecrypted = 0; 
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, NULL, 
             keyPtr, kCCKeySizeAES256, 
             ivPtr /* initialization vector (optional) */, 
             [self bytes], dataLength, /* input */ 
             buffer, bufferSize, /* output */ 
             &numBytesDecrypted); 

if (cryptStatus == kCCSuccess) 
{ 
    return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 
} 

free(buffer); //free the buffer; 
return nil; 
} 

@end 



@interface t() 
@end 

@implementation t 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 


NSString *key = @"12345678123456781234567812345678"; 

NSData *plaintext = [[@"aaa0000000000000" dataUsingEncoding:NSASCIIStringEncoding] AES256EncryptWithKey: key]; 

label1.text = [[NSString alloc] initWithData:plaintext encoding:NSASCIIStringEncoding]; 


} 

@end 

И теперь код PHP:

<?php 

$key256 = "12345678123456781234567812345678"; 
$iv128 = "1234567812345678"; 
$text = "aaa"; 

$blocksize = 16; 
$len = strlen($text); 
$pad = $blocksize - ($len % $blocksize); 

$text .= str_repeat("0", $pad); 

$cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key256, $text, MCRYPT_MODE_CBC, $iv128); 

echo $cipher; 

?> 

Xcode зашифрованная строка и PHP зашифрованная строка отличается.

PHP: â5¢Ð[Iüf#hÂ(Æ

Xcode: ¡#yZPbEs¿D6ñ

Что я могу сделать, чтобы заставить его работать? Я делаю что-то неправильно?

я более подробно объяснить, что код делает и как он структурирован таким образом, вы можете легче понять проблему (поправьте меня, если я ошибаюсь):

  1. Оба PHP и Xcode использовать CBC для шифрования AES так Наверное, там нет проблем.

  2. Как вы можете видеть, я просто пытаюсь получить тот же результат - безопасность здесь не имеет значения - поэтому я не использовал прописку - текст имеет ровно 128 бит в длину (16 символов).

  3. Ключ - 256 бит (32 символа).

  4. Инициализационный вектор - 128 бит (16 символов).

спасибо.

Любая помощь приветствуется!

+0

Строка '- (NSData *) AES256EncryptWithKey: (NSString *) key {' правильно определяет тот же ключ, что и PHP, не так ли? – LSerni

+0

Да. Вы можете видеть обе клавиши в моем коде. – BechD

ответ

2

Наконец получил его! (после запроса Apple об этом)

Очевидно, что получение getCString из NSString неверно, потому что процедура пытается обнулить строку, а 32-байтовый буфер недостаточно велик, чтобы прервать строку из 32 символов.

Правильный способ получить ключ или IV будет:

[key cStringUsingEncoding:NSASCIIStringEncoding]; 
+0

Я не получаю никакого правильного значения так же, как PHP :( –

0

Изменение:

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding]; 

в

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

Я считаю, что это проблема кодирования

+0

Нет ... это тоже был мой исходный код ... Не имеет значения, если это UTF8 или ASCII - шифрование точно такое же: ¡# yZPbEs¿D6 – BechD

0

При использовании этого кода с самого начала страницы, я могу зашифровать только 16 символов текста. На самом деле я могу зашифровать любой размер текста, но когда я расшифровываю зашифрованные NSData, я получаю только 16 символов или 128 бит.

Это имеет какое-то отношение к IV? Является ли этот код для шифрования ТОЛЬКО 128 бит, и если у меня больше размер текста, мне нужно предоставить (для лучшей безопасности) новый IV и зашифровать второй блок?

+0

Да, приведенный выше код использовался только для шифрования 16 байтов в качестве теста совместимости между iOS и php. Попробуйте заменить NULL в «CCCrypt (kCCDecrypt, kCCAlgorithmAES128, NULL, ...» с помощью kCCOptionPKCS7Padding.) Опять же - теперь у вас не будет те же результаты с php, поскольку php использует другую функцию заполнения. – BechD

+0

Хорошо, я просто проверял, нормально ли я это реализовал. Но подождите, что добавление PKCS7 связано с обычным вводом текста? Не заполняется ли только ключ - если клавиша короткая, а затем набивать ее нулями? – jovanjovanovic

+0

Нет, для текста используется отступы. AES 128 работает только с блоками текста 128 бит ... Таким образом, ваш текст должен быть дополнен, чтобы его можно было точно разделить блоки из 128 бит. – BechD