为什么CryptoSwift函数ChaCha20(键:"键",iv:" Iv")返回nil而不是抛出错误?

时间:2016-01-01 17:48:56

标签: encryption swift2 optional cryptoswift

我目前正在尝试创建自己的密码管理器应用程序,类似于master password,它使用算法生成密码,因此不必存储在客户端计算机上或在线。

为实现这一目标,我决定使用CryptoSwift库使用ChaCha20密码算法。这是我目前的代码(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)。我得到的错误是"致命错误:在解开一个Optional值"时意外地发现了nil。这可能是由于'!'在加密方法之前,因为其他一切都在之前工作。我试过更换'!'然后变量encrypted等于nil,如果我删除了'!'或'?'总而言之,我得到了语法错误。

如何在let encrypted = try ChaCha20(key: "Key", iv: "Iv")!.encrypt(UInt8Array)行修复此问题?

2 个答案:

答案 0 :(得分:4)

ChaCha20的密钥大小为128或256位(16或32字节)。你传递了3个字节。 “IV”(这里真的是nonce)是8个字节。你正在通过2.你不应该期望这个构造一个密码对象。因为它没有,你得到零,然后当你申请!时,它会按照你的要求崩溃(这就是!的意思)。

您需要创建一个正确大小的随机密钥和随机数。如果您有密码,则需要使用适当的KDF(例如PBKDF2)将其转换为密钥。

如果你不清楚这些,那么你还没有建立安全密码管理器所需的技能,你真的应该停下来研究如何安全地实施密码学。我并不是说你是一个糟糕的开发人员或者不熟悉Cocoa开发。 非常很容易创建看起来安全并且由“安全”组件构成的完全不安全的加密系统。如果这是您感兴趣的领域,我强烈推荐Coursera的Cryptography I课程。密码学并不是一个不能用一点努力倾斜的深奥之谜,但它肯定不直观,绝大多数加密工具(包括CryptoSwift)假设你已经知道你在做什么。

如果您想要现成的东西来处理许多硬件,那么您可能需要查看RNCryptor。对于您自己的个人密码管理器而言,这可能就足够了,但我绝不建议为没有建立加密系统的强大基础的其他人构建密码管理器(即使您选择RNCryptor来实现它)。密码管理器对于在没有强大基础的情况下构建过于安全至关重要。

答案 1 :(得分:1)

您写道:

  

这可能是由于'!'之前的加密方法   在此之前其他一切都有效。我试过更换'!'同   然而,加密的变量等于nil

这也是正确的答案。问题是为什么函数/或构造函数ChaCha20(key: "Key", iv: "Iv")返回nil并且没有抛出错误。有两种可能性,(a)ChaCha20不会按定义抛出错误或(b)参数正常,结果仍为零。您必须检查CryptoSwift框架文档,因为您的问题是ChaCha20由于某种原因而失败,而不是您自己的代码。

UPDATE! 我检查了CryptoSwift并找到了

public init?(key:[UInt8], iv:[UInt8]) {
        if let c = contextSetup(iv: iv, key: key) {
            context = c
        } else {
            return nil
        }
    }

代码中的参数错误(使用String而不是[UInt8])。您确定,您使用的是有效版本的库吗?您没有从编译器收到任何错误,因为您的代码可以执行...请检查它。