Swift - 使用用户密码加密和解密字符串

Mat*_*ley 6 encryption swift

我正在尝试使用Swift中的密码加密String,但不知道如何操作.我需要像下面这样工作的东西

let password = "password"
let message = "messageToEncrypt"
let encryptedMessage = encrypt(message, password)
...

let decryptedMessage = decrypt(encryptedMessage, password)
Run Code Online (Sandbox Code Playgroud)

任何建议将不胜感激.

谢谢

更新 < - 立即删除此部分

更新2

好的,我现在有以下内容:

 func testEnc() throws {

    let ivKey = "tEi1H3E1aj26XNro"
    let message = "Test Message"
    let password = "pass123"

    let aesKey = password.padding(toLength: 32, withPad: "0", startingAt: 0)

    do {
        let messageArray = Array(message.utf8)
        let encrypted = try AES(key: aesKey, iv: ivKey, blockMode: .CBC, padding: .pkcs7).encrypt(messageArray)
        let encryptedString = String.init(bytes: encrypted, encoding: .utf8)
        let decrypted = try AES(key: aesKey, iv: ivKey, blockMode: .CBC, padding: .pkcs7).decrypt(encrypted)
        let decryptedString = String.init(bytes: decrypted, encoding: .utf8)
        assert(message == decryptedString)
    } catch {
        print(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,消息被正确加密并再次解密.

decryptedString返回message完美相同的值.但是我需要存储加密值.在上面的代码中encryptedString总是返回nil.AES是否将Array<UInt8>类加密为字节串?

Mat*_*ley 16

请参阅下面的更新部分.我已经离开了被删除的部分,以提供评论的背景,并说明如何不出于安全目的

我使用CryptoSwift进行了解决

func testEnc() throws {

    //has to be 16 characters
    //ivKey is only hardcoded for use of this example
    let ivKey = "tEi1H3E1aj26XNro"
    let message = "Test Message"
    let password = "pass123"

    //key has to be 32 characters so we pad the password
    let aesKey = password.padding(toLength: 32, withPad: "0", startingAt: 0)

    let encrypted = try message.encryptToBase64(cipher: AES(key: aesKey, iv: ivKey, blockMode: .CBC, padding: .pkcs7))
    //returns: beQ7u8hBGdFYqNP5z4gBGg==

    let decrypted = try encrypted?.decryptBase64ToString(cipher: AES(key: aesKey, iv: ivKey, blockMode: .CBC, padding: .pkcs7))
    //returns: Test Message
    assert(message == decrypted)

}
Run Code Online (Sandbox Code Playgroud)

UPDATE

上述方法虽然有效但却不安全; 请阅读有关此答案的评论以获取更多信息

根据评论和反馈,我编写了一个使用框架RNCryptor的新示例

要加密和解密消息,我使用以下两种方法.

    func encryptMessage(message: String, encryptionKey: String) throws -> String {
        let messageData = message.data(using: .utf8)!
        let cipherData = RNCryptor.encrypt(data: messageData, withPassword: encryptionKey)
        return cipherData.base64EncodedString()
    }

    func decryptMessage(encryptedMessage: String, encryptionKey: String) throws -> String {

        let encryptedData = Data.init(base64Encoded: encryptedMessage)!
        let decryptedData = try RNCryptor.decrypt(data: encryptedData, withPassword: encryptionKey)
        let decryptedString = String(data: decryptedData, encoding: .utf8)!

        return decryptedString
    }
Run Code Online (Sandbox Code Playgroud)

在我的用例中,我需要能够根据密码处理加密和解密,密码可以在不必重新加密所有内容的情况下进行更改.

我所做的是生成一个随机的32个字符串,并用密码加密.如果用户更改了密码,他们只需使用旧密码解密密钥,然后使用新密码对其进行重新加密.这确保了所有现有内容都可以被解密,同时仍然受到用户密码的保护.

要生成加密密钥,请使用以下方法:

func generateEncryptionKey(withPassword password:String) throws -> String {
    let randomData = RNCryptor.randomData(ofLength: 32)
    let cipherData = RNCryptor.encrypt(data: randomData, withPassword: password)
    return cipherData.base64EncodedString()
}
Run Code Online (Sandbox Code Playgroud)

注意:您只需为用户生成一次此加密密钥,因为它将存储在用户可以使用其密码返回的位置.

  • 我同意建造这个井非常困难.这就是为什么我向你指出了RNCryptor,它为你做了所有这些.有关该过程的说明,请参阅https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md. (2认同)
  • @MatthewCawley,也考虑多个用户共享相同密码的情况. (2认同)