Index

API

WebAuthn.WebAuthnModule
module WebAuthn

A Julia package for WebAuthn/FIDO2 credential registration and authentication in web applications.

Supports all required cryptographic formats: CBOR/COSE, Ed25519 (OKP), ECDSA (P-256), RSA public keys, base64url, and PEM export. Utility functions simplify browser-challenge generation, and parsing and verification of registration and authentication responses.

source
WebAuthn.EC2PublicKeyType
struct EC2PublicKey

Represent a COSE kty=2 EC2 public key (P-256/ES256).

Fields:

  • x::Vector{UInt8} # x coordinate
  • y::Vector{UInt8} # y coordinate
  • alg::Int # COSE alg, usually -7
  • crv::Int # COSE curve, usually 1 (P-256)

See also: RSAPublicKey and OKPPublicKey.

source
WebAuthn.assetMethod
asset(name::AbstractString)::String

Read and return the contents of an asset script (e.g. JS file) shipped with WebAuthn.jl. Example: WebAuthn.asset("webauthn_register.js")

source
WebAuthn.asset_pathMethod
asset_path(name::AbstractString)::String

Get absolute path to an asset shipped with WebAuthn.jl.

source
WebAuthn.authentication_optionsMethod
authentication_options(rpid; allow_credential_ids=[], 
    challenge=nothing, timeout=60000, kwargs...)::Dict

Build a browser authentication options dictionary for navigator.credentials.get.

Keywords

  • allow_credential_ids: List of credential IDs (strings) that are allowed (default: empty).
  • challenge: Challenge string to use (default: random).
  • timeout: Timeout in milliseconds (default: 60000).
  • kwargs: Any additional field for WebAuthn/PublicKeyCredentialRequestOptions; future extensions or browser-specific options can be passed directly as keywords.

Examples

julia> using WebAuthn

julia> opts = authentication_options("example.com";
           allow_credential_ids=["id1", "id2"], userVerification="required", 
           extensions=Dict("appid"=>true));

julia> opts["rpId"]
"example.com"

julia> opts["allowCredentials"][1]["id"]
"id1"

julia> opts["userVerification"]
"required"

julia> opts["extensions"]["appid"]
true

See also: registration_options.

source
WebAuthn.base64urldecodeMethod
base64urldecode(s::AbstractString)::Vector{UInt8}

Decode a base64url string (URL-safe, no padding) to a byte vector.

Restores standard base64 alphabet and adds padding if necessary before decoding.

Examples

julia> using WebAuthn

julia> base64urldecode("AQID")
3-element Vector{UInt8}:
 0x01
 0x02
 0x03

See also: base64urlencode.

source
WebAuthn.base64urlencodeMethod
base64urlencode(bytes::Vector{UInt8})::String

Encode a byte vector to a base64url string without padding.

Replaces + with - and / with _ for URL safety, then removes padding characters.

Examples

julia> using WebAuthn

julia> base64urlencode(UInt8[1, 2, 3])
"AQID"

See also: base64urldecode.

source
WebAuthn.cose_key_parseMethod
cose_key_parse(cose::Dict)::WebAuthnPublicKey

Parse a COSE_Key dictionary to the appropriate public key struct.

Examples

julia> using WebAuthn

julia> cose = Dict(1=>2, 3=>-7, -1=>1, -2=>rand(UInt8,32), -3=>rand(UInt8,32));

julia> key = cose_key_parse(cose);

See also: EC2PublicKey, RSAPublicKey and OKPPublicKey.

source
WebAuthn.cose_key_to_pemMethod
cose_key_to_pem(key::WebAuthnPublicKey)::String

Convert a WebAuthn public key struct to PEM SubjectPublicKeyInfo string.

Creates a standard PEM format public key from a parsed WebAuthn/COSE public key (e.g., EC2PublicKey, RSAPublicKey, or OKPPublicKey) for use with external cryptographic libraries.

Examples

julia> using WebAuthn

julia> key = EC2PublicKey(rand(UInt8,32), rand(UInt8,32), -7, 1);

julia> pem = cose_key_to_pem(key);

See also: cose_key_parse.

source
WebAuthn.der_to_pemFunction
der_to_pem(derbytes::Vector{UInt8}, label::String = "CERTIFICATE")::String

Convert DER-encoded bytes to a PEM string with the specified label.

Formats binary DER data as a PEM-encoded string, splitting base64 lines to 64 characters and adding header and footer lines for the given type.

Examples

julia> using WebAuthn

julia> pem = WebAuthn.der_to_pem(rand(UInt8, 90), "PUBLIC KEY");

See also: cose_key_to_pem.

source
WebAuthn.extract_credential_public_keyMethod
extract_credential_public_key(authData::Vector{UInt8})::Vector{UInt8}

Extract the credential public key bytes from authenticator data.

Returns the raw CBOR-encoded public key (COSE_Key) after parsing authData as specified by the WebAuthn/FIDO2 standard.

Examples

julia> using WebAuthn

julia> fake_pk = UInt8[0xa5, 0x01, 0x02, 0x03, 0x38, 0x20, 0x01, 0x33, 0x58, 
       0x20];

julia> authData = vcat(zeros(UInt8, 37+16), 
       0x00, 0x10, rand(UInt8, 16), fake_pk);

julia> pkbytes = extract_credential_public_key(authData);

See also: parse_credential_public_key

source
WebAuthn.extract_pubkey_pem_from_derMethod
extract_pubkey_pem_from_der(der::Vector{UInt8})::String

Extract a PEM-encoded EC public key from a DER-encoded X.509 certificate.

Searches the provided DER bytes for a known EC OID and extracts the embedded public key, returning it as a PEM-encoded SubjectPublicKeyInfo suitable for cryptographic libraries.

Examples

julia> using WebAuthn

julia> der = [
           0x30,0x59,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,
           0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,0x03,0x42,0x00,
           0x04,0xac,0x21,0x45,0xb3,0x77,0x1d,0xdd,0xab,0xbd,0x1c,0x34,0x5e,
           0xed,0x9d,0x6a,0x81,0xd9,0x32,0x42,0xe0,0xaf,0xf4,0x77,0x07,0xf0,
           0x65,0x64,0x69,0xae,0x95,0x50,0xfe,0x86,0x21,0xba,0xcf,0xb5,0x43,
           0xaf,0x90,0xe2,0xda,0xf4,0x2f,0x9f,0x9b,0x71,0x09,0x55,0x7a,0x53,
           0xc3,0x63,0x1e,0xb9,0xa9,0x3f,0xfb,0x66,0x32,0xfa,0x3a,0x49,0x01,
           0x01 ];

julia> pem = WebAuthn.extract_pubkey_pem_from_der(der);

See also: cose_key_to_pem and der_to_pem.

source
WebAuthn.generate_challengeFunction
generate_challenge([n=32])::String

Generate a random base64url-encoded challenge of n bytes.

Examples

julia> using WebAuthn

julia> challenge = generate_challenge();

julia> length(base64urldecode(challenge))
32
source
WebAuthn.parse_assertionMethod
parse_assertion(authdata_b64, sig_b64) -> (authData, signature)

Base64url-decode authenticatorData and signature as a tuple of byte vectors.

Returns the authenticator data and signature, each as a vector of bytes.

Examples

julia> using WebAuthn

julia> ad_b64 = base64urlencode(rand(UInt8, 37));

julia> sig_b64 = base64urlencode(rand(UInt8, 64));

julia> ad, sig = parse_assertion(ad_b64, sig_b64);

See also: parse_attestation_object and parse_clientdata_json.

source
WebAuthn.parse_attestation_objectMethod
parse_attestation_object(b64::String)::Dict

Parse a base64url-encoded attestationObject to a dictionary.

Decodes and parses the CBOR-encoded attestation object returned during WebAuthn registration.

Examples

julia> using WebAuthn, CBOR

julia> attObj_b64 =
           "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVikgokmRebwXda2X9CScZAt1" *
           "FS1U7jvFi6aDLY8eyICQjhBAAAAAcDiKS6EGVQBSZ3UWJ8FVioAIJYypOb6RxF" *
           "Q4ocIvwK78qeEYp67CAWrj59jW99h8_tNpQECAyYgASFYIOyFijz315Yd_Aexkt" *
           "5l6YaFK4MK2CQgRZPXQqGGD06MIlgg54dhMxLg9u84Y3urvWdHrViXea0aMYq7v" *
           "7QI-DP1Duk";

julia> obj = parse_attestation_object(attObj_b64);

See also: parse_clientdata_json.

source
WebAuthn.parse_clientdata_jsonMethod
parse_clientdata_json(b64::String)::Dict

Parse a base64url-encoded clientDataJSON to a dictionary.

Decodes the clientDataJSON, converting from base64url and UTF-8 JSON to a Julia dictionary.

Examples

julia> using WebAuthn

julia> json = """{"type": "webauthn.get"}""";

julia> cdj_b64 = base64urlencode(Vector{UInt8}(json));

julia> cdj = parse_clientdata_json(cdj_b64)
Dict{String, Any} with 1 entry:
  "type" => "webauthn.get"

See also: parse_attestation_object.

source
WebAuthn.parse_credential_public_keyMethod
parse_credential_public_key(authData::Vector{UInt8})::WebAuthnPublicKey

Extract and parse credential public key from authenticator data.

Reads the CBOR-encoded credentialPublicKey field from authData and returns the corresponding parsed struct (e.g., EC2PublicKey, RSAPublicKey, or OKPPublicKey).

Examples

julia> using WebAuthn, CBOR

julia> fake_pk = CBOR.encode(Dict(1=>2, 3=>-7, -1=>1, -2=>rand(UInt8,32), 
                 -3=>rand(UInt8,32)));


julia> authData = vcat(zeros(UInt8, 37+16), 0x00, 0x20, rand(UInt8, 32), 
          fake_pk);

julia> key = parse_credential_public_key(authData);

See also: extract_credential_public_key and cose_key_parse.

source
WebAuthn.parse_ec_pem_xyMethod
parse_ec_pem_xy(pem::AbstractString)

Extract XY EC coordinates from a PEM/SPKI P-256 public key.

Parses a PEM-encoded (or plain DER) SubjectPublicKeyInfo containing a P-256 (secp256r1) uncompressed EC public key, as produced for WebAuthn and most browsers or OpenSSL tools. Returns X and Y coordinates of the EC point, each as a 32-byte vector.

Handles both short- and long-form DER length encodings, and scans all BIT STRING tags for an uncompressed point (0x04 prefix, 65 bytes total). Raises an error if not found.

Example

julia> using WebAuthn

julia> pem = """
       -----BEGIN PUBLIC KEY-----
       MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK4CWBHImRgAVPXrmUD7VhNFW1sUs
       GI17tvaN6KEkBukdOj8cXnZSnhFuPrf8ajP8KrRoYiZqHVFy8zyrPJzFnw==
       -----END PUBLIC KEY-----
       """;

julia> x, y = parse_ec_pem_xy(pem);

julia> length(x), length(y)
(32, 32)

See also: pem_to_der, parse_rsa_pem_ne and parse_ed25519_pem_x.

source
WebAuthn.parse_ed25519_pem_xMethod
parse_ed25519_pem_x(pem::AbstractString)::x::Vector{UInt8}

Extract the x-coordinate (32 bytes) from an Ed25519 public key (PEM/SPKI).

Parses a PEM-encoded Ed25519 SubjectPublicKeyInfo as generated by OpenSSL or Python and returns the 32-byte raw public key (x). This is useful for verifying Ed25519 signatures.

Example

julia> using WebAuthn

julia> pem = """
       -----BEGIN PUBLIC KEY-----
       MCowBQYDK2VwAyEAoi3rnmJUD+qXNlp2pBkQWpXCUUjccW+6Ue5r0QDPF94=
       -----END PUBLIC KEY-----
       """;

julia> x = parse_ed25519_pem_x(pem);

julia> length(x)
32

See also: pem_to_der and parse_ec_pem_xy.

source
WebAuthn.parse_rsa_pem_neMethod
parse_rsa_pem_ne(pem::AbstractString)

Extract the modulus (n) and exponent (e) from an RSA public key (PEM/SPKI).

Reads a PEM-encoded RSA SubjectPublicKeyInfo (as produced by OpenSSL, browser tools, etc.) and returns the modulus and exponent as byte vectors suitable for cryptographic use.

Raises an error if the ASN.1 structure is unexpected or unsupported.

Example

julia> using WebAuthn

julia> pem = """
       -----BEGIN PUBLIC KEY-----
       MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2auHrQvvpQv/DI1wQAmd
       YCUYzOr8hWU2rMtDEae/p5Cu5pyNJRdv7DjOdOeWeWq1rA/Od/GY/HYazst1lWMC
       XjiW3nf0yV1jHoXl9Dc1wFTxl7EKrykK2EsijB8f93f4scxEalIyfjauXC6hIPi4
       /yWGS8cJOuj35ac/7N6GrUMIdzCj0qumTrUhRkmsJo2HtGm3dKkEZxHnL7fs/hln
       wwVOl2rqH0EcaVBSZwvjuEt6EfVMhqINp9FhRaIq5gx0ZpBR6OpFPM5oXrtMgsKO
       vIdZK7yZPcKw0JLmymZMi5gjgGVTX48YHoM8Mi6KtB4k2Rbp3Ouqc56odpLx2K2S
       cwIDAQAB
       -----END PUBLIC KEY-----
       """;

julia> n, e = parse_rsa_pem_ne(pem);

julia> length(n) > 200 && e == UInt8[0x01, 0x00, 0x01]
true

See also: pem_to_der and parse_ec_pem_xy.

source
WebAuthn.pem_to_derMethod
pem_to_der(pem::AbstractString)::Vector{UInt8}

Decode a PEM-formatted string (e.g., a PEM public key or certificate) to a DER-encoded byte vector.

Strips header/footer and whitespace, decodes the enclosed base64.

Example

julia> using WebAuthn

julia> pem = """
       -----BEGIN PUBLIC KEY-----
       MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK4CWBHImRgAVPXrmUD7VhNFW1sUs
       GI17tvaN6KEkBukdOj8cXnZSnhFuPrf8ajP8KrRoYiZqHVFy8zyrPJzFnw==
       -----END PUBLIC KEY-----
       """;

julia> der = WebAuthn.pem_to_der(pem);
source
WebAuthn.registration_optionsMethod
registration_options(rpid, rpname, user_id, user_name, user_display;
    exclude_ids=[], challenge=nothing,
    attestation="none", timeout=60000, kwargs...)::Dict

Construct WebAuthn registration options for navigator.credentials.create.

Arguments

  • rpid: relying party identifier (e.g., "example.com").
  • rpname: display name of the RP.
  • user_id: user handle (string or byte vector).
  • user_name: username (string).
  • user_display: display name (string).

Keywords

  • exclude_ids: vector of credential IDs to exclude (default empty).
  • challenge: challenge string to use (default: random).
  • attestation: "none" (default), "packed", "direct", "enterprise", etc.
  • timeout: timeout in ms (default 60000).
  • kwargs: any additional WebAuthn/PublicKeyCredentialCreationOptions fields; future extensions can be set directly as keywords.

Examples

julia> using WebAuthn

julia> opts = registration_options("foo.com", "Demo", 123, "bob", 
           "Bob", attestation="packed", extensions=Dict("my_custom"=>"hi"));

julia> opts["attestation"]
"packed"

julia> opts["extensions"]["my_custom"]
"hi"

See also: authentication_options.

source
WebAuthn.verify_attestation_objectMethod
verify_attestation_object(attObj_b64, clientDataJSON)::Bool

Verify a WebAuthn attestation object of format "none" or "packed".

Examples

julia> using WebAuthn

julia> attObj_b64 =
       "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVikgokmRebwXda2X9CScZAt1" *
       "FS1U7jvFi6aDLY8eyICQjhBAAAAAcDiKS6EGVQBSZ3UWJ8FVioAIJYypOb6RxF" *
       "Q4ocIvwK78qeEYp67CAWrj59jW99h8_tNpQECAyYgASFYIOyFijz315Yd_Aexkt" *
       "5l6YaFK4MK2CQgRZPXQqGGD06MIlgg54dhMxLg9u84Y3urvWdHrViXea0aMYq7v" *
       "7QI-DP1Duk";

julia> cdj_b64 =
       "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiazF6eV9hU0N" *
       "PTDdOMFBWVmFVVElpVm5BU1ZGVDE4MDB1TWJVa1R2dUdKSSIsIm9yaWdpbiI6Im" *
       "h0dHBzOi8vd2ViYXV0aG4tdGVzdC5sb2NhbCIsImNyb3NzT3JpZ2luIjpmYWxze" *
       "X0";

julia> clientDataJSON = WebAuthn.base64urldecode(cdj_b64);

julia> ok = verify_attestation_object(attObj_b64, clientDataJSON)
true

See also: verify_webauthn_signature.

source
WebAuthn.verify_attestation_packedMethod
verify_attestation_packed(attStmt::Dict, msg::Vector{UInt8},
    authData::Vector{UInt8}[, clientDataJSON::Vector{UInt8}])::Bool

Verify a WebAuthn "packed" attestation statement (e.g., self-attested Ed25519 / ECDSA / RSA, as used in device authentication).

On success, returns true; otherwise, returns false. For Ed25519 (OKP, alg -8), the signature must be over SHA256(clientDataJSON) (not the full authData || SHA256(clientDataJSON)).

Examples

julia> using WebAuthn, CBOR, Sodium, SHA

julia> pk = Vector{UInt8}(undef, Sodium.crypto_sign_PUBLICKEYBYTES);

julia> sk = Vector{UInt8}(undef, Sodium.crypto_sign_SECRETKEYBYTES);

julia> Sodium.crypto_sign_keypair(pk, sk);

julia> cose = Dict(1=>1, 3=>-8, -1=>6, -2=>pk);

julia> cbor_pk = CBOR.encode(cose);

julia> rpId = "example.com";

julia> rpIdHash = SHA.sha256(Vector{UInt8}(rpId));

julia> flags = 0x41; signCount = UInt8[0,0,0,1]; aaguid = zeros(UInt8,16);

julia> credId = rand(UInt8,16); credIdLen = [UInt8(length(credId) >> 8), 
           UInt8(length(credId)&0xff)];

julia> authData = vcat(rpIdHash, flags, signCount, aaguid, credIdLen, 
           credId, cbor_pk);

julia> clientDataJSON = b"""{"type":"webauthn.create","challenge":"abc",
            "origin":"https://example.com"}""";

julia> clientDataHash = SHA.sha256(clientDataJSON);

julia> sig = Vector{UInt8}(undef, Sodium.crypto_sign_BYTES);

julia> sl = Ref{UInt64}();

julia> Sodium.crypto_sign_detached(sig, sl, clientDataHash, 
            length(clientDataHash), sk);

julia> msg = vcat(authData, clientDataHash);

julia> attStmt = Dict("sig"=>sig, "alg"=>-8);

julia> verify_attestation_packed(attStmt, msg, authData)
true

julia> attStmt_bad = deepcopy(attStmt); attStmt_bad["sig"][1] ⊻= 0xFF;

julia> verify_attestation_packed(attStmt_bad, msg, authData)
false
source
WebAuthn.verify_challengeMethod
verify_challenge(clientDataJSON_b64, expected_challenge_b64)::Bool

Verify the clientDataJSON challenge matches the expected challenge.

Examples

julia> using WebAuthn, JSON3

julia> challenge = generate_challenge(16);

julia> cdj = JSON3.write(Dict("type"=>"webauthn.create",
            "challenge"=>challenge, "origin"=>"https://site"));

julia> cdj_b64 = base64urlencode(Vector{UInt8}(cdj));

julia> verify_challenge(cdj_b64, challenge)
true

See also: generate_challenge

source
WebAuthn.verify_p256_signature_raw_xyMethod
verify_p256_signature_raw_xy(x, y, digest, sig)::Bool

Verify a P-256 ECDSA sig with OpenSSL using raw pubkey XY, SHA256 digest, and DER-encoded signature.

Examples

julia> using WebAuthn, SHA

julia> x = UInt8[
           0x7d, 0xf1, 0xb2, 0x85, 0x1d, 0xdc, 0x04, 0x29,
           0xdf, 0x71, 0xbd, 0x49, 0x9f, 0xea, 0x1d, 0xef,
           0xca, 0x63, 0x4c, 0x5c, 0xbe, 0x8e, 0xaa, 0xa5,
           0xcd, 0x3b, 0xa6, 0x65, 0xb7, 0xba, 0x3e, 0x32
       ];

julia> y = UInt8[
           0x6e, 0x33, 0x03, 0x54, 0xd9, 0x5f, 0x0d, 0xb7,
           0x28, 0x69, 0xec, 0x9a, 0x47, 0x82, 0x99, 0xe4,
           0xe9, 0x34, 0x44, 0xe4, 0x8d, 0x40, 0x8f, 0xbe,
           0xa1, 0x61, 0xf9, 0x3a, 0x4f, 0xd2, 0x14, 0xb8
       ];

julia> msg    = b"test message";

julia> digest = SHA.sha256(msg);

julia> sig = UInt8[
           0x30, 0x45, 0x02, 0x21, 0x00, 0xa9, 0xe7, 0x2a,
           0x18, 0x6a, 0xe2, 0xa3, 0x5d, 0x7a, 0x34, 0xa2,
           0x60, 0xef, 0xff, 0x36, 0x27, 0xbb, 0x59, 0x31,
           0xf9, 0xe3, 0xdb, 0xe5, 0xf8, 0x0a, 0xa2, 0xff,
           0x3f, 0xad, 0x2e, 0x3c, 0x79, 0x02, 0x20, 0x74,
           0x24, 0x4a, 0xb1, 0x19, 0xf2, 0x70, 0x4f, 0xa2,
           0x62, 0xdc, 0x87, 0x6c, 0x6b, 0xeb, 0xda, 0x77,
           0xe1, 0x5a, 0x5a, 0x13, 0xb9, 0xec, 0x87, 0x4e,
           0x29, 0x4b, 0x25, 0x95, 0x83, 0xc9, 0xdf];

julia> WebAuthn.verify_p256_signature_raw_xy(x, y, digest, sig)
true

julia> sig2 = copy(sig); sig2[1] ⊻= 0xFF;

julia> WebAuthn.verify_p256_signature_raw_xy(x, y, digest, sig2)
false
source
WebAuthn.verify_rsa_signature_raw_neMethod
verify_rsa_signature_raw_ne(n, e, digest, sig)::Bool

Verify an RSA PKCS1v1.5/SHA256 signature using raw modulus and exponent buffers, with everything in memory.

Examples

julia> using WebAuthn, SHA, Test

julia> n = UInt8[0xc8,0xac,0xb4,0xd0,0x1c,0x87,0x78,0x45,0x1d,0xcc,0xfa,
                 0xee,0x0a,0xe1,0x38,0xb4,0x12,0x71,0xf2,0x85,0x9d,0x00,
                 0xb1,0xf8,0x01,0x74,0x01,0xb9,0xcc,0x8f,0x02,0xda,0x6b,
                 0xa3,0x7a,0xe3,0xd8,0x35,0x00,0x63,0x52,0x16,0x4e,0xfc,
                 0xe3,0x8b,0xd0,0x88,0x8e,0xa8,0x03,0x6c,0x56,0x38,0x1f,
                 0x85,0xfd,0xf4,0xc0,0xa4,0x5b,0x6c,0x3f,0x0d];

julia> e = UInt8[0x01, 0x00, 0x01];

julia> msg = b"hello RSA";

julia> digest = SHA.sha256(msg);

julia> sig = UInt8[0x15,0xe4,0xed,0xd0,0x0a,0xe1,0x62,0xda,0xe5,0x84,0xb6,
                   0x9c,0x91,0x96,0x5e,0xba,0xa8,0x3a,0x01,0x55,0xc5,0x6e,
                   0x06,0xce,0xd5,0xd1,0x02,0x49,0x17,0x4c,0xb4,0xbf,0x36,
                   0x77,0x88,0x48,0x46,0x59,0x2e,0xd9,0xac,0x3e,0xcd,0x83,
                   0x69,0xab,0x46,0x8a,0xfe,0xa8,0xd0,0xee,0x1f,0x9c,0xfd,
                   0xe1,0xd9,0x03,0x57,0x70,0x34,0xe5,0x80,0xeb];

julia> WebAuthn.verify_rsa_signature_raw_ne(n, e, digest, sig)
true

julia> sig_bad = copy(sig);

julia> sig_bad[1] ⊻= 0xFF;

julia> WebAuthn.verify_rsa_signature_raw_ne(n, e, digest, sig_bad)
false
source
WebAuthn.verify_webauthn_signatureFunction
verify_webauthn_signature(key_or_pem, authenticatorData, clientDataJSON, 
    signature)::Bool

Verify a WebAuthn assertion signature for the given public key or PEM.

Examples

julia> using WebAuthn, Sodium, SHA

julia> pk = Vector{UInt8}(undef, Sodium.crypto_sign_PUBLICKEYBYTES);

julia> sk = Vector{UInt8}(undef, Sodium.crypto_sign_SECRETKEYBYTES);

julia> Sodium.crypto_sign_keypair(pk, sk);

julia> key = OKPPublicKey(pk, -8, 6);

julia> ad = rand(UInt8, 37);

julia> cdj = rand(UInt8, 32);

julia> msg = vcat(ad, SHA.sha256(cdj));

julia> sig = Vector{UInt8}(undef, Sodium.crypto_sign_BYTES);

julia> sl = Ref{Culonglong}();

julia> Sodium.crypto_sign_detached(sig, sl, msg, length(msg), sk);

julia> valid = verify_webauthn_signature(key, ad, cdj, sig)
true

See also: cose_key_to_pem and parse_assertion.

source