Параметр заполнения CCCrypt, похоже, не влияет на расшифровку

У меня есть строка, зашифрованная с помощью Java

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(text.getBytes());    

(Обратите внимание, что в Java PKCS5Padding фактически является PKCS7Padding при использовании AES ссылка)

И мой внутренний код расшифровки:

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                      kCCAlgorithmAES128,
                                      0,
                                      key.bytes,
                                      kCCBlockSizeAES128,
                                      iv.bytes,
                                      [encrypted bytes],
                                      dataLength,
                                      buffer,
                                      bufferSize,
                                      &numBytesEncrypted);

называется так:

let decryptedData = decryptor.AES128DecryptWithKeyString(key, encryptedString: encodedString) //this does the CCCrypt stuff
let string:NSString = NSString(data: decryptedData, encoding: NSUTF8StringEncoding) ?? ""
let data = NSData(base64EncodedString: string as String, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)

Таким образом, даже несмотря на то, что он был зашифрован с помощью PKCS5Padding, моя расшифровка работает нормально, несмотря на то, что опция заполнения не указана. Кроме того, если я изменю параметр 0 на kCCOptionPKCS7Padding, он также будет работать для расшифровки.

Это ожидаемое поведение? Параметр заполнения актуален только для kCCEncrypt, а не для kCCDecrypt?

Кроме того, если мы изменим шифрование Java на

Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");

и заполнить полезную нагрузку вручную нулевыми байтами, тогда она все равно правильно расшифровывается независимо от того, использую ли я 0 в качестве опции или kCCOptionPKCS7Padding


person Will M.    schedule 06.01.2016    source источник


Ответы (1)


Когда вы говорите, что заполнение не влияет на расшифровку, вы смотрите на вывод в шестнадцатеричном дампе?

Заполнение будет состоять из завершающих символов в диапазоне от 0x01 до 0x10, которые не являются печатаемыми символами ASCII, поэтому они могут выглядеть одинаково при печати строки, зашифрованной с помощью заполнения PKCS#7, но расшифрованной с помощью параметра заполнения.

Добавьте образец вывода в обоих направлениях в виде шестнадцатеричного дампа к вопросу, и вы должны увидеть, что происходит на самом деле.

Статус возврата не указывает на правильную расшифровку или недопустимое заполнение, а указывает только на грубые ошибки вызова.

Пример:

let keyData     = Array("12345678901234567890123456789012".utf8)
let messageData = Array("Don´t try".utf8)

let encrypted = testCrypt(data:messageData, keyData:keyData, operation:kCCEncrypt, options:UInt32(kCCOptionPKCS7Padding))!
print("encrypted:       \(encrypted)")

let decryptedPKCS7 = testCrypt(data:encrypted, keyData:keyData, operation:kCCDecrypt, options:UInt32(kCCOptionPKCS7Padding))!
print("decrypted PKCS7: \(decryptedPKCS7)")

let decryptedNone = testCrypt(data:encrypted, keyData:keyData, operation:kCCDecrypt, options:UInt32(0))!
print("decrypted None:  \(decryptedNone)")

Выход:

encrypted:       [136, 95, 194,  76, 137, 107, 196,  39, 245, 108, 106, 84, 139, 49, 14, 139]  
decrypted PKCS7: [68, 111, 110, 194, 180, 116,  32, 116, 114, 121]  
decrypted None:  [68, 111, 110, 194, 180, 116,  32, 116, 114, 121,   6,  6,   6,  6,  6,   6]  

Замыкающие шесть байтов 0x06 представляют собой неудаленное заполнение.

person zaph    schedule 06.01.2016
comment
Я смотрю на NSData, а также превращаю его в UIImage, и он отображается правильно. - person Will M.; 07.01.2016
comment
Я вижу в NSData дополнительные байты заполнения, когда я не указываю kCCOptionPKCS7Padding, но я не понимаю, почему при преобразовании его обратно в кодированные данные base64 для UIImage let data = NSData(base64EncodedString: string as String, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) байты заполнения исчезают. (Они исчезают даже без опции IgnoreUnknownCharacters) - person Will M.; 07.01.2016
comment
Поскольку данные недействительны (содержат символы заполнения), операция не определена. - person zaph; 07.01.2016