-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signature validates locally but not on remote server #31
Comments
Hi! Thanks for letting me know about this use case! It was slightly tricky. 2 things where off.
I managed to produce a valid JWToken
Here's the code import EllipticCurveKeyPair
extension Data {
func base64EncodedStringURISafe() -> String {
return self.base64EncodedString()
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
}
}
func DEREC256SignatureDecode(_ signature: Data) -> Data {
// example https://lapo.it/asn1js/#3046022100F309E36DFA5FE0BFBF5C3855E06E9C3C7D04DE347E2B345C3392DDB98E13BE6302210080372B3BBAE5E370B976092B8AA64F4EF1025FFE893D0046FA085F256AE04761
var decoded = signature
let maxChunkSize = 32
decoded.removeFirst() // removing sequence header
decoded.removeFirst() // removing sequence size
decoded.removeFirst() // removing 'r' element header
let rLength = Int(decoded.removeFirst()) // removing 'r' element length
let r = decoded.prefix(rLength).suffix(maxChunkSize) // read out 'r' bytes and discard any padding
decoded.removeFirst(Int(rLength)) // removing 'r' bytes
decoded.removeFirst() // 's' element header
let sLength = Int(decoded.removeFirst()) // 's' element length
let s = decoded.prefix(sLength).suffix(maxChunkSize) // read out 's' bytes and discard any padding
return Data(r) + Data(s)
}
let keysManager: EllipticCurveKeyPair.Manager = {
let publicAccessControl = EllipticCurveKeyPair.AccessControl(protection: kSecAttrAccessibleAlwaysThisDeviceOnly, flags: [])
let privateAccessControl = EllipticCurveKeyPair.AccessControl(protection: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, flags: [.privateKeyUsage, .userPresence])
let config = EllipticCurveKeyPair.Config(
publicLabel: "test.sign.public",
privateLabel: "test.sign.private",
operationPrompt: "Json web token",
publicKeyAccessControl: publicAccessControl,
privateKeyAccessControl: privateAccessControl,
token: .secureEnclave)
return EllipticCurveKeyPair.Manager(config: config)
}()
func testJWT() {
do {
try? keysManager.deleteKeyPair()
let headerAndPayload = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJ0ZXN0dXNlcm5hbWUiLCJzdWIiOiJ0ZXN0Y2xpZW50aWQiLCJpYXQiOjE1MDE1MDk3ODIsImV4cCI6MTUwMTUwOTg0Mn0"
let derSignature = try keysManager.sign(headerAndPayload.data(using: .utf8)!, hash: .sha256)
let decodedSignature = DEREC256SignatureDecode(derSignature)
let token = headerAndPayload + "." + decodedSignature.base64EncodedStringURISafe()
print("headerAndPayloadAsString: \(headerAndPayload)")
print("signature: \(derSignature.base64EncodedStringURISafe())")
print("decoded signature: \(decodedSignature.base64EncodedStringURISafe())")
print("token: \(token)")
print("public key: \n\(try keysManager.publicKey().data().PEM)")
try keysManager.verify(signature: derSignature,
originalDigest: headerAndPayload.data(using: .utf8)!,
hash: .sha256)
print("valid!")
} catch {
print("error: \(error)")
}
}
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
testJWT()
}
|
There's some mutual interests here yourkarma/JWT#116 |
Hi, everything works! I'm really grateful for the speed of response and example! |
Great! I'm keeping this open until I have this included somehow |
That would be nice too. The sign method could have a param like so
but this is just a suggestion |
👍👍 Yep, either that or return an object with two variables. |
Hi, I wanto to use your library for my project which uses JSON Web Token
JWT = base64(header) + "." + base64(payload) + "." + base64(signature)
In the documentation of my project I have an example
And when I paste that token here https://jwt.io/ with the public key - it validates.
However when I use your library to sign the header and payload I get info about invalid signature (on JWT page)
The verification passes your method
Unbased content of header and payload are
Am I doing something wrong with signing?
The text was updated successfully, but these errors were encountered: