Comments (6)
Hi! Thanks for letting me know about this use case!
It was slightly tricky. 2 things where off.
- The signature that Security/EllipticCurveKeyPair produces is in DER format. The API expects a raw signature of 64 bytes for ES256.
- The API expects a base64 uri safe variant
I managed to produce a valid JWToken
eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJ0ZXN0dXNlcm5hbWUiLCJzdWIiOiJ0ZXN0Y2xpZW50aWQiLCJpYXQiOjE1MDE1MDk3ODIsImV4cCI6MTUwMTUwOTg0Mn0.9bUeggjl9sOdfxqOOcMv7uE6MUBrhEMWEFDLI1xiD4HwO8oSK_TuveST4imEug13h7hthgy1uwYPa0Fb7M4N3w
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXum2ZYo0Qp2foJRIKPP2eGNT82y6
GgZgRGKWB8DArDhKQAhjp/RQFCoP8Olq4QtL5l4jcdKZhvOTAd47r7tAvQ==
-----END PUBLIC KEY-----
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()
}
from ellipticcurvekeypair.
There's some mutual interests here yourkarma/JWT#116
from ellipticcurvekeypair.
Hi, everything works! I'm really grateful for the speed of response and example!
from ellipticcurvekeypair.
Great! I'm keeping this open until I have this included somehow
from ellipticcurvekeypair.
That would be nice too. The sign method could have a param like so
enum SignatureFormat {
case der
case raw
}
public func sign(_ digest: Data, hash: Hash, format: SignatureFormat = .der, context: LAContext? = nil) throws -> Data {
}
but this is just a suggestion
from ellipticcurvekeypair.
👍👍 Yep, either that or return an object with two variables.
from ellipticcurvekeypair.
Related Issues (20)
- Can I export the EC Private key ? HOT 2
- no prompts shown for face id auth on simulator HOT 5
- Encrypting messages using CLI Open SSL HOT 5
- deinitialize() and deallocate() causing Compiler Error in SHA256.swift HOT 6
- Demo Project Error HOT 2
- iOS 13 and CryptoKit HOT 1
- Error when signing or decrypting on Simulator (iOS 13) HOT 2
- Publish new version in CocoaPods? HOT 1
- Encryption on MacOS
- Wrong Simulator Detection
- AccessControl for publicKey doesn't restrict to biometryCurrentSet flag HOT 3
- SecItemCopyMatching not works in iphone 12 HOT 6
- Sign twice strings HOT 2
- Is secp256k1 curve supported?
- Create access control with only [.privateKeyUsage] HOT 3
- concern about userPresence HOT 2
- Authenticate only with Biometrics
- Deprecation Warnings and Making export() Method of PublicKey Public HOT 6
- iOS 13+ HOT 3
- Unable to generate key pair
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ellipticcurvekeypair.