我在这里做错了什么?它在解密时抛出下面的错误(在倒数第二行)
致命错误:“try!”表达式意外引发错误:CryptoKit.CryptoKitError.authenticationFailure
func encryptDecryptWithNonceTag(){
let secret = "my-xxx-bit-secret-my-secret-my-s"
let mySymKey = SymmetricKey(data: secret.data(using: .utf8)!)
let plain = "Say hello to my little friend!"
let nonce = try! AES.GCM.Nonce(data: Data(base64Encoded: "fv1nixTVoYpSvpdA")!)
let tag = Data(base64Encoded: "e1eIgoB4+lA/j3KDHhY4BQ==")!
//ENCRYPT
let sealedBox = try! AES.GCM.seal(plain.data(using: .utf8)!, using: mySymKey, nonce: nonce, authenticating: tag)
let ciphertext = sealedBox.ciphertext.base64EncodedString()
print("ciphertext: \(ciphertext)")
//DECRYPT: Recreate sealedbox with nonce and tag and then decrypt
let sealedBoxRecreated = try! AES.GCM.SealedBox(nonce: nonce,
ciphertext: Data(base64Encoded: ciphertext)!,
tag: tag)
let decrypted = try! AES.GCM.open(sealedBoxRecreated, using: mySymKey)
print("decryptedtext:\(String(decoding: decrypted, as: UTF8.self))")
}
2条答案
按热度按时间bvhaajcl1#
您在
authenticating
参数中使用标记进行加密和解密。加密时不应提供预定义的标记。输出
顺便说一句,不要在你的代码中使用
try!
。因为每当一个异常get抛出(try失败),你的代码就会崩溃。更糟糕的情况是,当调试时,你无法看到真实的的问题。所以总是使用catch块。kt06eoxx2#
当创建用于加密的密封框时,
authenticating
参数应包含应进行身份验证但不加密的数据。这不是任何类型的密钥,也不是解密所需的内容。例如,在邮件中,您希望接收者进行身份验证(所以没有人可以弄乱这个字段),但你不希望它加密,因为中间人将需要它来实际发送邮件给它。tag
是你想放在这里的。注意,你可能可以传递一些空的东西。关于用于解密的密封框,您现在明白了不应该传递与前面的
authenticating
参数中相同的数据。密封盒由三部分组成:密文、随机数和认证标签。
正如您在its documentation中所看到的,您可以单独使用这三个组件创建密封的盒子,也可以将它们全部组合起来(这只是将它们的数据一个接一个地放置)。
这就是为什么你会得到一个身份验证错误:你传递一个随机的身份验证标记而不是正确的,所以它告诉你的消息不能被身份验证。
因此,您还需要从
sealedBox
(sealedBox.tag
)中提取身份验证标记,并将其提供给sealedBoxRecreated
(在tag:
参数处)。结果:
您还可以简单地导出“组合”内容,这会更好-因为nonce每次都应该更改,它可能需要与消息沿着进行通信。