swift 使用CryptoKit获取带有随机数和标签的Authenticationfailure

bpsygsoo  于 2023-04-04  发布在  Swift
关注(0)|答案(2)|浏览(155)

我在这里做错了什么?它在解密时抛出下面的错误(在倒数第二行)
致命错误:“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))")
}
bvhaajcl

bvhaajcl1#

您在authenticating参数中使用标记进行加密和解密。加密时不应提供预定义的标记。

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")!)

    // ENCRYPT
    let sealedBox = try! AES.GCM.seal(plain.data(using: .utf8)!, using: mySymKey, nonce: nonce)
    let ciphertext = sealedBox.ciphertext.base64EncodedString()
    print("ciphertext: \(ciphertext)")
    print("tag: \(sealedBox.tag.base64EncodedString())")

    
    //DECRYPT: Recreate sealedbox with nonce and tag and then decrypt
    let sealedBoxRecreated = try! AES.GCM.SealedBox(nonce: nonce,
                                                    ciphertext: Data(base64Encoded: ciphertext)!,
                                                    tag: sealedBox.tag)
    do {
        let decrypted = try AES.GCM.open(sealedBoxRecreated, using: mySymKey)
        print("decryptedtext: \(String(decoding: decrypted, as: UTF8.self))")
    } catch {
        print("Error decrypting: \(error.localizedDescription)")
    }
    
}

输出

顺便说一句,不要在你的代码中使用try!。因为每当一个异常get抛出(try失败),你的代码就会崩溃。更糟糕的情况是,当调试时,你无法看到真实的的问题。所以总是使用catch块。

kt06eoxx

kt06eoxx2#

当创建用于加密的密封框时,authenticating参数应包含应进行身份验证但不加密的数据。这不是任何类型的密钥,也不是解密所需的内容。例如,在邮件中,您希望接收者进行身份验证(所以没有人可以弄乱这个字段),但你不希望它加密,因为中间人将需要它来实际发送邮件给它。

  • 〉所以我不认为tag是你想放在这里的。注意,你可能可以传递一些空的东西。
    关于用于解密的密封框,您现在明白了不应该传递与前面的authenticating参数中相同的数据。
    密封盒由三部分组成:密文、随机数和认证标签。
  • 密文,顾名思义,就是加密的内容。在这个算法中,它应该和原始文本一样长。
  • 随机数就像一个种子,它被用来在加密中增加更多的随机性-但它不是密钥,它可以是公共的。最重要的是,它应该只使用一次(因此它的名字),每次使用都要改变(你可以简单地使用计数器)。因此,相同的输入消息不会以相同的方式加密两次。
  • 现在验证标记就像校验和:它在加密期间被计算,并且被用于认证发送者。

正如您在its documentation中所看到的,您可以单独使用这三个组件创建密封的盒子,也可以将它们全部组合起来(这只是将它们的数据一个接一个地放置)。
这就是为什么你会得到一个身份验证错误:你传递一个随机的身份验证标记而不是正确的,所以它告诉你的消息不能被身份验证。
因此,您还需要从sealedBoxsealedBox.tag)中提取身份验证标记,并将其提供给sealedBoxRecreated(在tag:参数处)。
结果:

//ENCRYPT
let sealedBox = try! AES.GCM.seal(plain.data(using: .utf8)!,
    using: mySymKey,
    nonce: nonce,
    authenticating: Data())

let ciphertext = sealedBox.ciphertext.base64EncodedString()
let tag = sealedBox.tag.base64EncodedString()
    
//DECRYPT: Recreate sealedbox with nonce and tag and then decrypt
let sealedBoxRecreated = try! AES.GCM.SealedBox(nonce: nonce,
    ciphertext: Data(base64Encoded: ciphertext)!,
    tag: Data(base64Encoded: tag)!)

您还可以简单地导出“组合”内容,这会更好-因为nonce每次都应该更改,它可能需要与消息沿着进行通信。

//ENCRYPT
let sealedBox = try! AES.GCM.seal(plain.data(using: .utf8)!,
    using: mySymKey,
    nonce: nonce,
    authenticating: Data())

let cipheredMessage = sealedBox.combined.base64EncodedString()
    
//DECRYPT: Recreate sealedbox with nonce and tag and then decrypt
let sealedBoxRecreated = try! AES.GCM.SealedBox(combined: Data(base64Encoded: cipheredMessage)!)

相关问题