Posts

Post marked as solved
11 Replies
Hi again, thanks for the reply! I have tried the .ecdsaSignatureMessageX962SHA384 algorithm before, but without converting the raw signature into X9.62 format. This saves the day: let dataSignatureX962 = try! P384.Signing.ECDSASignature(rawRepresentation: dataSignature).derRepresentation It works now, thank you for your time and the support!
Post marked as solved
11 Replies
Oh, sorry, it's a simple function to satisfy the base64 length requirements: import Foundation import CryptoKit class JWTValidator { static func validateSignature() { let jwtToken = "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.VUPWQZuClnkFbaEKCsPy7CZVMh5wxbCSpaAWFLpnTe9J0--PzHNeTFNXCrVHysAa3eFbuzD8_bLSsgTKC8SzHxRVSj5eN86vBPo_1fNfE7SHTYhWowjY4E_wuiC13yoj" let publicKeyBase64 = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEC1uWSXj2czCDwMTLWV5BFmwxdM6PX9p+Pk9Yf9rIf374m5XP1U8q79dBhLSIuaojsvOT39UUcPJROSD1FqYLued0rXiooIii1D3jaW6pmGVJFhodzC31cy5sfOYotrzF" let parts = jwtToken.components(separatedBy: ".") let header = parts[0] let payload = parts[1] let signature = parts[2] let dataPublicKey = Data(base64Encoded: publicKeyBase64)! let dataSigned = (header + "." + payload).data(using: .ascii)! let dataSignature = Data(base64Encoded: base64StringWithPadding(base64str: signature))! if #available(iOS 14.0, *) { let ck = try! P384.Signing.PublicKey(derRepresentation: dataPublicKey) let x963 = ck.x963Representation let publicKey = SecKeyCreateWithData(x963 as NSData, [ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClass as String: kSecAttrKeyClassPublic, ] as NSDictionary, nil)! print(publicKey) // we have the SecKey representation of the public key. // validate the JWT with the public key. var validateError : Unmanaged<CFError>? let algorithm: SecKeyAlgorithm = .eciesEncryptionStandardX963SHA384AESGCM let result = SecKeyVerifySignature(publicKey, algorithm, dataSigned as NSData, dataSignature as NSData, &validateError) if let validateError = validateError { print(validateError) } print("JWT is valid: \(result)") // prints JWT is valid: false } } static func base64StringWithPadding(base64str: String) -> String { var newStr = base64str.replacingOccurrences(of: "-", with: "+") .replacingOccurrences(of: "_", with: "/") let count = newStr.count % 4 if count > 0 { let amount = 4 - count for _ in 0..<amount { newStr += "=" } } return newStr } }
Post marked as solved
11 Replies
I see now. Here's the example: import Foundation import CryptoKit let jwtToken = "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.VUPWQZuClnkFbaEKCsPy7CZVMh5wxbCSpaAWFLpnTe9J0--PzHNeTFNXCrVHysAa3eFbuzD8_bLSsgTKC8SzHxRVSj5eN86vBPo_1fNfE7SHTYhWowjY4E_wuiC13yoj" let publicKeyBase64 = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEC1uWSXj2czCDwMTLWV5BFmwxdM6PX9p+Pk9Yf9rIf374m5XP1U8q79dBhLSIuaojsvOT39UUcPJROSD1FqYLued0rXiooIii1D3jaW6pmGVJFhodzC31cy5sfOYotrzF" let parts = jwtToken.components(separatedBy: ".") let header = parts[0] let payload = parts[1] let signature = parts[2] let dataPublicKey = Data(base64Encoded: publicKeyBase64)! let dataSigned = (header + "." + payload).data(using: .ascii)! let dataSignature =  Data(base64Encoded: base64StringWithPadding(base64str: signature))! let ck = try! P384.Signing.PublicKey(derRepresentation: dataPublicKey) let x963 = ck.x963Representation let publicKey = SecKeyCreateWithData(x963 as NSData, [ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClass as String: kSecAttrKeyClassPublic, ] as NSDictionary, nil)! print(publicKey) // we have the SecKey representation of the public key. // validate the JWT with the public key. var validateError : Unmanaged<CFError>? let algorithm: SecKeyAlgorithm = .eciesEncryptionStandardX963SHA384AESGCM let result = SecKeyVerifySignature(publicKey,                                    algorithm,                                    dataSigned as NSData,                                    dataSignature as NSData,                                    &validateError) if let validateError = validateError { print(validateError) } print("JWT is valid: \(result)") // prints JWT is valid: false I can't realise what should be the SecKeyAlgorithm (if that's the problem at all). Thank you for the assistance!
Post marked as solved
11 Replies
If you post a self-contained example, I’d be happy to look at it. I think I can't understand what kind of an example I need to provide. It's just the JWTValidator that I have posted in the question. My use case is: I have a hardware bluetooth device with a JWT token. I have also the public key. The goal is to validate that JWT token with the existing public key and prove the device is the correct one. So I'm trying to achieve this firstly with the JWT token and public key posted above (taken from the jwt.io standard ES384 example). Then I'll test with the real data from the product. I'll be more than happy to provide any additional info you need! Thank you!
Post marked as solved
11 Replies
Hi, Eskimo! Thank you for the quick reply! I'm using the ASN1Decoder because we're supporting iOS 12 +. I have the public key in SecKey format, but I'm struggling to verify the provided JWT token with that key. SecKeyVerifySignature always returns false. What am I missing?
Post not yet marked as solved
1 Replies
To everyone, who is also struggling with this issue - I'm glad to inform you that building with the new Xcode 14.0 beta version seems to fix the issue, but introduces some new ones: The widgets doesn't disappear anymore! They do disappear during the installation(which is normal), but appears again after the install completes. Sometimes the today widgets displays "Unable to Load" after update. The widgets built with the WidgetKit (the iOS 14+ widgets) shows only white (or black, depending on the device theme) on the screen after the update. Tapping on them opens the app, but the deep linking doesn't work. It looks like the widgets are gone. You can't add new one. The worst is phone reboot doesn't fix this bug. The only fix I've found so far is downgrading to version built with Xcode 13. Overall I can't run WidgetKit widget on iOS 15 iPhone. On iOS 16 simulator it works fine. Tested on iOS 15.4.1. Build uploaded to TestFlight with Xcode 14.0 beta. Now let's hope Apple will get it in order until the official Xcode version.
Post not yet marked as solved
17 Replies
Exactly same with me! When I first install the version, which includes the watch app, the message is not sent. Only after restarting the iPhone it starts working. Tested on multiple iPhones and watches. But can't reproduce it on simulator. What is the solution? To tell the users to restart the phone when they install the watch app? Ridiculous!!
Post not yet marked as solved
14 Replies
In iOS 13.3 I still can reproduce this bug. I'm always getting "NEHotspotConfigurationErrorDomain Code=8 "internal error."" After device restart - works as expected. Any ideas when this will be fixed?