Я работаю в AES256, чтобы иметь возможность шифровать/дешифровать между iOS и PHP с использованием небезопасных каналов.
Я видел много похожих вопросов, которые касаются размера ключа, режима (CBC или ECB), использования случайного iv и т.д. Но в этом случае я нашел странное поведение следующим образом.
Конфигурация в обеих средах: - Ключ: 32 байта (256 бит) - Размер блока: 128 бит (стандартный) - iv: 16 байт (статические для целей тестирования) - Режим: CBC
Если я зашифрую текст 16 или 32 байта (чтобы соответствовать размеру блока AES), результат в Swift и PHP похожи, но не совсем одинаковы:
key = "12345678901234567890123456789012" plainText = "12345678901234567890123456789012" iv = "1234567890123456"
Swift cipher = e5RnnlJkv4QGnGhkMwfvgMHr80NWUVhbvvfCdPQ5V2KyKJTx4KfWmn4HXi4dG0b8 PHP cipher = e5RnnlJkv4QGnGhkMwfvgMHr80NWUVhbvvfCdPQ5V2I =
Как вы можете видеть, разница в длине шифра и в последних двух символах строки PHP Base64.
Но если я использую текст, который не является множителем блока размера AES128, давайте скажем "Hello World", в средах бота сообщается о разных (но одинаковых размерах) шифрах следующим образом
Swift cipher = bdwO/5C8a + pliIoIXtuzfA ==
PHP cipher = oPotHCkxpOwQhIaCz6hNMw ==
В обоих случаях (Swift и PHP) шифр дешифруется правильно независимо от размера открытого текста. Кроме того, результаты Swift соответствуют версии Objective-C кода
Прикрепленный упрощенный код:
PHP
$key = "12345678901234567890123456789012";
$iv = "1234567890123456";
$plaintext = "Hello World";
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
$ciphertext_base64 = base64_encode($ciphertext);
echo "ciphertext: ".$ciphertext_base64."</br>";
Свифта
let keyData: NSData! = (key as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let keyBytes = UnsafePointer<UInt8>(keyData.bytes)
let keyLength = size_t(kCCKeySizeAES256)
let plainData = (plainText as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let dataLength = UInt(plainData.length)
let dataBytes = UnsafePointer<UInt8>(plainData.bytes)
var bufferData = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
var bufferPointer = UnsafeMutablePointer<UInt8>(bufferData.mutableBytes)
let bufferLength = size_t(bufferData.length)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options = UInt32(kCCOptionPKCS7Padding)
let ivData: NSData! = (iv as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let ivPointer = UnsafePointer<UInt8>(ivData.bytes)
var numBytesEncrypted: UInt = 0
var cryptStatus = CCCrypt(operation, algoritm, options, keyBytes, keyLength, ivPointer, dataBytes, dataLength, bufferPointer, bufferLength, &numBytesEncrypted)
bufferData.length = Int(numBytesEncrypted)
let base64cryptString = bufferData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
println(base64cryptString)
Почему эти разные?