Почему функция CryptoSwift ChaCha20(ключ: "ключ", iv: "Iv") возвращает ноль вместо выдачи ошибки?
В настоящее время я пытаюсь сделать свое собственное приложение диспетчера паролей похожим на мастер-пароль, которое использует алгоритм для генерации паролей, чтобы их не нужно было хранить на клиентском компьютере или в Интернете.
Чтобы достичь этого, я решил использовать алгоритм шифрования ChaCha20 с использованием библиотеки CryptoSwift. Вот код, который у меня есть на данный момент (приложение OS X):
import Cocoa
import CryptoSwift
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification) {
do
{
let UInt8String = "Test".utf8
print("UTF8 string: \(UInt8String)")
let UInt8Array = Array(UInt8String)
print("UTF8 array: \(UInt8Array)")
let encrypted = try ChaCha20(key: "Key", iv: "Iv")!.encrypt(UInt8Array)
print("Encrypted data: \(encrypted)")
} catch _ {
}
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}
Строка, где я получаю ошибку let encrypted = try ChaCha20(key: "Key", iv: "Iv")!.encrypt(UInt8Array)
, Я получаю ошибку "Неустранимая ошибка: неожиданно найден ноль при развертывании необязательного значения". Это, вероятно, из-за '!' до метода шифрования, так как все остальное работает до этого. Я пытался заменить '!' с '?', однако переменная encrypted
тогда равен нулю, если я уберу '!' или же '?' в целом я получаю синтаксическую ошибку.
Как бы я исправить проблему на let encrypted = try ChaCha20(key: "Key", iv: "Iv")!.encrypt(UInt8Array)
линия?
2 ответа
Размер ключа ChaCha20 составляет 128 или 256 бит (16 или 32 байта). Вы передаете 3 байта. Значение "IV" (здесь на самом деле это nonce) составляет 8 байтов. Вы проходите 2. Вы не должны ожидать, что это создаст объект шифрования. Так как это не так, вы получаете ноль, а затем, когда вы подаете заявку !
он вылетает, как вы просили (вот что !
средства).
Вам нужно создать случайный ключ и одноразовые номера правильных размеров. Если у вас есть пароль, вам необходимо преобразовать его в ключ, используя соответствующий KDF, такой как PBKDF2.
Если вам что-то непонятно, значит, у вас еще нет набора навыков, необходимого для создания безопасного менеджера паролей, и вам действительно следует остановиться и изучить, как безопасно внедрить криптографию. Я не имею в виду, что вы плохой разработчик или не знакомы с разработкой Cocoa. Очень легко создать абсолютно небезопасные системы шифрования, которые выглядят безопасными и состоят из "безопасных" компонентов. Если это область, которая вас интересует, я настоятельно рекомендую курс Криптографии I от Coursera. Криптография не является какой-то глубокой загадкой, на которую нельзя опираться с небольшим усилием, но она определенно не интуитивна, и подавляющее большинство криптографических инструментов (включая CryptoSwift) предполагают, что вы уже знаете, что делаете.
Если вы хотите что-то готовое, которое обрабатывает многие из твердых деталей для вас, то вы можете взглянуть на RNCryptor. Этого может быть достаточно для вашего собственного персонального менеджера паролей, но я бы никогда не предложил создавать менеджер паролей для других, не имея надежных основ построения криптосистем (даже если вы выбрали RNCryptor для его реализации). Менеджеры паролей слишком важны с точки зрения безопасности, чтобы их можно было построить без прочной основы в теме.
Вы написали:
Это, вероятно, из-за '!' до метода шифрования, так как все остальное работает до этого. Я пытался заменить '!' с '?', однако зашифрованная переменная тогда равна нулю
Это тоже правильный ответ. Вопрос в том, почему функция / или конструктор ChaCha20(key: "Key", iv: "Iv")
возвращает ноль и не выдает ошибку. Есть две возможности: (а) ChaCha20 не выдает ошибку по определению или (б) параметры в порядке, а результат по-прежнему равен нулю. Вы должны проверить документацию по фреймворку CryptoSwift, потому что ваша проблема в том, что по какой-то причине произошел сбой ChaCha20, а не в вашем собственном коде.
ОБНОВИТЬ! Я проверил CryptoSwift и нашел
public init?(key:[UInt8], iv:[UInt8]) {
if let c = contextSetup(iv: iv, key: key) {
context = c
} else {
return nil
}
}
Параметры в вашем коде неверны (вы используете String, а не [UInt8]). Вы уверены, что используете действующую версию библиотеки? Вы не получили никаких ошибок от компилятора, потому что ваш код может быть выполнен... Проверьте это, пожалуйста.