我正在尝试在 Swift 中使用密码来加密字符串,但不确定该怎么做。我需要这样的东西

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

如有任何建议,我们将不胜感激。

谢谢

更新

基于下面的想法,我有以下方法

func testEnc() throws { 
     
    let ivKey = "tEi1H3E1aj26XNro" 
    let message = "Test Message" 
    let password = "pass123" 
     
    let aesKey = password.padding(toLength: 32, withPad: "0", startingAt: 0) 
     
    let aes = try AES(key: aesKey, iv: ivKey) 
    let cipherBytes: Array<UInt8> = try aes.encrypt(Array(message.utf8)) 
     
    let cipherData = NSData(bytes: cipherBytes, length: Int(cipherBytes.count)) 
    let cipherString = cipherData.base64EncodedString(options: .lineLength64Characters) 
    //cipherString => beQ7u8hBGdFYqNP5z4gBGg== 
    let decryptedCipherBytes = try aes.decrypt(Array(cipherString.utf8)) 
    let decryptedCipherData = NSData(bytes: decryptedCipherBytes, length: Int(cipherBytes.count)) 
    let decryptedCipherString = decryptedCipherData.base64EncodedString(options: .lineLength64Characters) 
     
    assert(message == decryptedCipherString) 
} 

在线

    let decryptedCipherBytes = try aes.decrypt(Array(cipherString.utf8)) 

我收到以下错误:

[CryptoSwift.AES.Error: dataPaddingRequired] 
Conform 'CryptoSwift.AES.Error' to Debugging.Debuggable to provide more debug information. 

你知道为什么它不能解密刚刚加密的数据吗?

谢谢

请您参考如下方法:

请参阅下面删除部分的更新部分。我已经留下了删除部分,以便为评论提供上下文,并展示出于安全目的如何不这样做

我已经使用 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) 
 
} 

<罢工>

更新

上述方法虽然可行,但并不安全; 请阅读对此答案的评论以获取更多信息

根据评论和反馈,我编写了一个使用框架的新示例 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 
    } 

在我的用例中,我需要能够根据可以更改的密码处理加密和解密,而无需重新加密所有内容。

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

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

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

注意:您只会为用户生成此加密 key 一次,因为它随后会存储在某个地方,用户可以使用他们的密码返回它。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!