webauthn-swift
webauthn-swift copied to clipboard
WebAuthnError(reason: PassDemo.WebAuthnError.Reason.invalidAttestationObject)
import UIKit import CryptoKit import SafariServices import AuthenticationServices
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webAuthnManager = WebAuthnManager(
configuration: WebAuthnManager.Configuration(
relyingPartyID: "domain.ai",
relyingPartyName: "My Fancy Web App",
relyingPartyOrigin: "https://domain.ai"
)
)
Task {
let result = webAuthnManager.beginRegistration(user: PublicKeyCredentialUserEntity(id: self.generateRandomBytes(count: 10), name: "Jaydip", displayName: "Jaydip Finava"))
print(result)
let id = result.user.id.base64URLEncodedString()
let data = generateClientDataJSON(challenge: Data(result.challenge)
, origin: "https://domia.ai", type: "webauthn.create", tokenBinding: nil) print(data!)
let byteArray: [UInt8] = Array(data!)
let newData = generateDataJSON()!
let byteArray1: [UInt8] = Array(newData)
let request = RegistrationCredential(id: id, type: .publicKey, rawID: result.challenge, attestationResponse: AuthenticatorAttestationResponse(clientDataJSON: byteArray, attestationObject: byteArray1))
//RegistrationCredential(id: id, type: CredentialType.publicKey, rawID: result.user.id, attestationResponse: AuthenticatorAttestationResponse(clientDataJSON: [UInt8].random(count: 32), attestationObject: [UInt8].random(count: 32)))
let confirmCredentialIDNotRegisteredYet: (String) async throws -> Bool = { credentialID in
return true
}
do {
let credential = try await webAuthnManager.finishRegistration(
challenge: result.challenge,
credentialCreationData: request,
confirmCredentialIDNotRegisteredYet: confirmCredentialIDNotRegisteredYet
)
print(credential)
} catch {
print(error)
}
}
}
func generateRandomBytes(count: Int) -> [UInt8] {
var randomBytes = [UInt8]()
for _ in 0..<count {
let randomByte = UInt8(arc4random_uniform(UInt32(UInt8.max)))
randomBytes.append(randomByte)
}
return randomBytes
}
func generateClientDataJSON(challenge: Data, origin: String, type: String, tokenBinding: String?) -> Data? {
var clientData: [String: Any] = [
"challenge": challenge.base64EncodedString(),
"origin": origin,
"type": type
]
if let tokenBinding = tokenBinding {
clientData["tokenBinding"] = tokenBinding
}
do {
let jsonData = try JSONSerialization.data(withJSONObject: clientData)
return jsonData
} catch {
print("Error serializing client data JSON: \(error)")
return nil
}
}
func generateDataJSON() -> Data? {
let clientData: [String: Any] = [
"rpIdHash": sha256("domain.ai"),
"signCount": 0
]
do {
let jsonData = try JSONSerialization.data(withJSONObject: clientData)
return jsonData
} catch {
print("Error serializing client data JSON: \(error)")
return nil
}
}
func sha256(_ input: String) -> String {
// Convert the input string to data using UTF-8 encoding
guard let inputData = input.data(using: .utf8) else {
return ""
}
let hashedData = SHA256.hash(data: inputData)
// Convert the hash to a hexadecimal string
let hashString = hashedData.compactMap { String(format: "%02x", $0) }.joined()
return hashString
}
}
I recommend reading up on how Passkeys work on iOS and how you should be implementing them. You should not be using webAuthnManager
on iOS - that lives on your server. The iOS app is the client and should use ASAuthenticationServices
I have password manager app and I want to passkey for webauthn.io from my Auto fill extension is that possible? how can you give me sample code?
Begin registration works well here are the response of that method
PublicKeyCredentialCreationOptions(challenge: [175, 165, 121, 16, 203, 47, 228, 14, 38, 138, 152, 97, 202, 28, 17, 133, 103, 17, 53, 230, 251, 107, 245, 65, 161, 206, 227, 55, 1, 86, 239, 255], user: PassDemo.PublicKeyCredentialUserEntity(id: [71, 93, 209, 225, 177, 115, 193, 76, 130, 123], name: "Jaydip", displayName: "Jaydip Finava"), relyingParty: PassDemo.PublicKeyCredentialRelyingPartyEntity(id: "oloid.ai", name: "My Fancy Web App"), publicKeyCredentialParameters: [PassDemo.PublicKeyCredentialParameters(type: PassDemo.CredentialType(rawValue: "public-key"), alg: PassDemo.COSEAlgorithmIdentifier.algES256), PassDemo.PublicKeyCredentialParameters(type: PassDemo.CredentialType(rawValue: "public-key"), alg: PassDemo.COSEAlgorithmIdentifier.algES384), PassDemo.PublicKeyCredentialParameters(type: PassDemo.CredentialType(rawValue: "public-key"), alg: PassDemo.COSEAlgorithmIdentifier.algES512)], timeout: Optional(3600.0 seconds), attestation: PassDemo.AttestationConveyancePreference.none)
You cannot run it on the client - it is insecure and must be run on the server to verify the attestations
That’s sorted already now I need help to create authData object can you help me?
On Thu, 9 May 2024 at 12:27 PM, Tim Condon @.***> wrote:
You cannot run it on the client - it is insecure and must be run on the server to verify the attestations
— Reply to this email directly, view it on GitHub https://github.com/swift-server/webauthn-swift/issues/67#issuecomment-2102067854, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOLYOFMSOCTBDYRBPJGH63LZBMM4FAVCNFSM6AAAAABHLJIHU6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMBSGA3DOOBVGQ . You are receiving this because you authored the thread.Message ID: @.***>
It should be created by the iOS framework