我正在尝试在 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 一次,因为它随后会存储在某个地方,用户可以使用他们的密码返回它。