swiftapple-cryptokitcryptokit

Getting Authentcationfailure with nonce and tag using CryptoKit


What am I doing wrong here? It throws below error while decrypting (at second last line)

Fatal error: 'try!' expression unexpectedly raised an error: 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))")
}


Solution

  • You are using tag for both encryption and decryption in the authenticating parameter. You should not provide a pre determined tag while encrypting.

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

    output enter image description here

    Btw do not use try! in your code. Because whenever an exception get throws (try fails) your code will crash. Worse case is when debugging you are unable to see the real issue. So always use a catch block.