JOSESwift jwe encryption failed to decode in the nimbus server

1k Views Asked by At

Had anybody used JOSESwift successfully? In my case, decryption in the server failing, probably cannot find the matching private key or wrong with encryption. Getting error 500.

My code is, getting the public keys from a server.

keys?.keys?.forEach({ (key) in
                BPLogger.debug("\(key)")
                do {
                    let jwkData = key.toJSONString()?.data(using: .utf8)
                    let rsaKey = try RSAPublicKey(data: jwkData!)
                    BPLogger.log("key components: \(rsaKey.parameters)")
                    BpidCache.shared.joseRsaKey = rsaKey
                    self?.generateParametersJose()
                    completion()                        
                    return
                } catch  {
                    BPLogger.debug("Error: \(error)")
                }
            })

The server expected a 'kid' field in the jose header, which was missing in the framework. So I have added it... The backend Java server uses nimbus library.

 func generateParametersJose() {
        let rsa = BpidCache.shared.joseRsaKey
        var publicKey: SecKey? = nil
        do {
            publicKey = try rsa?.converted(to: SecKey.self)
        } catch {
            BPLogger.log("\(error)")
        }
        var header = JWEHeader(algorithm: .RSA1_5, encryptionAlgorithm: .A256CBCHS512)
//      header.parameters["kid"] = "1"
        let jwk = MidApi.Model.JWTKey(key: cek);
        let jwkData = try! JSONEncoder().encode(jwk)
        BPLogger.debug("jwkData = \(String(data: jwkData, encoding: .utf8)!)")
        let payload = Payload(jwkData)
        // Encrypter algorithms must match header algorithms.
        guard let encrypter = Encrypter<SecKey>(keyEncryptionAlgorithm: .RSA1_5, encryptionKey: publicKey!, contentEncyptionAlgorithm: .A256CBCHS512) else {
            return
        }
        guard let jwe = try? JWE(header: header, payload: payload, encrypter: encrypter) else {
            BPLogger.error("Falied jwe creation.")
            return
        }

        var comps = jwe.compactSerializedString.components(separatedBy: ".")
        var jweHeader = comps.first
        let data = jweHeader?.base64URLDecode()
        var orgH = try! JSONDecoder().decode(BPJweHeader.self, from: data!)
        orgH.kid = "1"
        let newJson = try! JSONEncoder().encode(orgH).base64URLEncodedString()
        comps[0] = newJson
        let newHeader = comps.joined(separator: ".")
        BPLogger.log("jwe.compactSerializedString = \(newHeader)")
        headers = ["X-Encrypted-Key": newHeader]
//      headers = ["X-Encrypted-Key": jwe.compactSerializedString] // this also fails
    }

What am I doing wrong?

1

There are 1 best solutions below

0
On BEST ANSWER

The latest version of JOSESwift (1.3.0) contains a fix for the problem that prevented setting additional header parameters.

You can now set the additional header parameters listed in RFC-7516. Setting the "kid" parameter like you tried to do in your question works like this:

var header = JWEHeader(algorithm: .RSA1_5, encryptionAlgorithm: .A256CBCHS512)

header.kid = "1"

If you use the framework via CocoaPods, make sure to run pod repo update to make sure you install the latest version which contains the fix.