-1

我目前正在尝试制作类似于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). 我得到的错误是“致命错误:在展开可选值时意外发现 nil”。这可能是由于'!' 在加密方法之前,因为在此之前一切正常。我试过替换'!' 带有“?”,但是encrypted如果我删除“!”,则变量等于nil 或者 '?' 我完全得到一个语法错误。

我将如何解决let encrypted = try ChaCha20(key: "Key", iv: "Iv")!.encrypt(UInt8Array)在线问题?

4

2 回答 2

5

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

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

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

如果你想要一些现成的东西来为你处理许多困难的部分,那么你可能想看看RNCryptor。这对于您自己的个人密码管理器可能就足够了,但我绝不会建议为没有构建加密系统的坚实基础的其他人构建密码管理器(即使您选择了 RNCryptor 来实现它)。密码管理器对安全性至关重要,如果没有坚实的主题基础,就无法构建。

于 2016-01-01T19:31:20.117 回答
1

你写了:

这可能是由于'!' 在加密方法之前,因为在此之前一切正常。我试过替换'!' 带有“?”,但是加密的变量等于 nil

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

更新!我检查了 CryptoSwift 并发现

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

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

于 2016-01-01T19:29:22.890 回答