IOS 3DES с возвратом ECB половинных прав

Появилась проблема с шифрованием пароля с помощью 3DES + ECB algo. Вот код, который я использую:

class func encryptPassword(pass: String) -> String {
 let keyString = "123456789012345678901234"
 let keyData: NSData! = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
 let keyBytes = UnsafePointer<*****>(keyData.bytes)
 let data: NSData! = (pass as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
 let dataLength = ****(data.length)
 let dataBytes = UnsafePointer<*****>(data.bytes)
 var cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES)!
 var cryptPointer = UnsafeMutablePointer<*****>(cryptData.mutableBytes)
 var cryptLength = size_t(cryptData.length)
 let keyLength = size_t(kCCKeySize3DES)
 let operation: CCOperation = ****32(kCCEncrypt)
 let algoritm: CCAlgorithm = ****32(kCCAlgorithm3DES)
 let options: CCOptions = ****32(kCCOptionECBMode | kCCOptionPKCS7Padding)
 var numBytesEncrypted :**** = 0
 var cryptStatus = CCCrypt(operation,
 algoritm,
 options,
 keyBytes, keyLength,
 nil,
 dataBytes, dataLength,
 cryptPointer, cryptLength,
 &numBytesEncrypted)
 var base64cryptString = ""
 if ****32(cryptStatus) == ****32(kCCSuccess) {
 let x: **** = numBytesEncrypted
 cryptData.length = Int(numBytesEncrypted)
 println("cryptLength = \(numBytesEncrypted),\n cryptData = \(cryptData)\n")
 base64cryptString = cryptData.base64EncodedStringWithOptions(nil)
 } else {
 println("Error: \(cryptStatus)")
 }
 return base64cryptString
 }
}
</*****></*****></*****>

Это работает, но не удалось проверить. Я использовал онлайн-шифр для этого, например http://www.tools4noobs.com/online_tools/encrypt/ Выберите TripleDES и ECB

Для кода

let encrypted = Utils.encryptPassword("123456789")

Консоль показывает

cryptData = <1dd50935 b702084b d164ce3e 9427c493>

Онлайн-конвертер показывает

1dd50935b702084bf9fbee67c9643874

Первые восемь байтов верны, но последние - нет. Как это могло быть? Что может быть неправильным с кодом?

=========== РЕДАКТИРОВАНИЕ ============

Как сказал @Artjom - в полный блок должны быть добавлены значения нулей.

Этот код в начале добавляет нулевые значения:

// Trim password
 var password = pass.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
 // Adding null padding
 let count = 8 - countElements(password) % 8
 for i in 1...count {
 password += "\0"
 }

Затем используйте "пароль" var вместо входящего "pass" для создания "данных"

А также удалите поле для параметров

let algoritm: CCAlgorithm = ****32(kCCAlgorithm3DES)

Спасибо

1 ответ

Возможно, это другое дополнение. DES имеет размер блока 8 байт. Итак, первый блок 12345678, а второй - 9. Поскольку DES является блочным шифром, открытый текст должен быть дополнен следующим размером блока.

В онлайн-инструменте, вероятно, используется нулевое заполнение или нет дополнения, что в основном означает, что остальные байты блока установлены в 0x00. Вы используете в своем коде, с другой стороны, дополнение PKCS # 7. Удалите флаг PKCS # 7, чтобы увидеть, соответствует ли результат.

Вам нужно будет выполнить нулевое дополнение, если библиотека не предоставит его. Заполните пароль байтами \0 до тех пор, пока во время шифрования не будет достигнут кратный размер блока и удалите эти нулевые байты во время дешифрования.

Не рекомендуется использовать шифрование без заполнения.

Кроме того, пароль обычно не зашифровывается, а скорее хешируется случайной солью и несколькими итерациями. Когда ваша пользовательская база данных "потеряна", вам не нужен тот, кто ее нашел, чтобы иметь возможность легко отменить пароли и войти в систему как любой пользователь (предположение, что ключ шифрования также легко "теряется" ). С другой стороны, использование сильной криптографической хэш-функции имеет то преимущество, что действительно невозможно изменить хэш.

licensed under cc by-sa 3.0 with attribution.