Index
WebAuthn.WebAuthn
WebAuthn.EC2PublicKey
WebAuthn.OKPPublicKey
WebAuthn.RSAPublicKey
WebAuthn.WebAuthnPublicKey
WebAuthn.asset
WebAuthn.asset_path
WebAuthn.authentication_options
WebAuthn.base64urldecode
WebAuthn.base64urlencode
WebAuthn.cose_key_parse
WebAuthn.cose_key_to_pem
WebAuthn.der_to_pem
WebAuthn.extract_credential_public_key
WebAuthn.extract_pubkey_pem_from_der
WebAuthn.generate_challenge
WebAuthn.parse_assertion
WebAuthn.parse_attestation_object
WebAuthn.parse_clientdata_json
WebAuthn.parse_credential_public_key
WebAuthn.parse_ec_pem_xy
WebAuthn.parse_ed25519_pem_x
WebAuthn.parse_rsa_pem_ne
WebAuthn.pem_to_der
WebAuthn.registration_options
WebAuthn.verify_attestation_object
WebAuthn.verify_attestation_packed
WebAuthn.verify_challenge
WebAuthn.verify_p256_signature_raw_xy
WebAuthn.verify_rsa_signature_raw_ne
WebAuthn.verify_webauthn_signature
WebAuthn.verify_webauthn_signature
API
WebAuthn.WebAuthn
— Modulemodule 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.
WebAuthn.EC2PublicKey
— Typestruct 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
.
WebAuthn.OKPPublicKey
— Typestruct OKPPublicKey
Represent a COSE kty=1 OKP public key (Ed25519).
Fields:
- x::Vector{UInt8} # public key bytes
- alg::Int # COSE alg, usually -8
- crv::Int # COSE curve ID, usually 6
See also: EC2PublicKey
and RSAPublicKey
.
WebAuthn.RSAPublicKey
— Typestruct RSAPublicKey
Represent a COSE kty=3 RSA public key.
Fields:
- n::Vector{UInt8} # modulus
- e::Vector{UInt8} # exponent
- alg::Int # COSE alg, usually -257
See also: EC2PublicKey
and OKPPublicKey
.
WebAuthn.WebAuthnPublicKey
— Typeabstract type WebAuthnPublicKey
Abstract supertype for all WebAuthn public key structs.
WebAuthn.asset
— Methodasset(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")
WebAuthn.asset_path
— Methodasset_path(name::AbstractString)::String
Get absolute path to an asset shipped with WebAuthn.jl.
WebAuthn.authentication_options
— Methodauthentication_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
.
WebAuthn.base64urldecode
— Methodbase64urldecode(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
.
WebAuthn.base64urlencode
— Methodbase64urlencode(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
.
WebAuthn.cose_key_parse
— Methodcose_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
.
WebAuthn.cose_key_to_pem
— Methodcose_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
.
WebAuthn.der_to_pem
— Functionder_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
.
WebAuthn.extract_credential_public_key
— Methodextract_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
WebAuthn.extract_pubkey_pem_from_der
— Methodextract_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
.
WebAuthn.generate_challenge
— Functiongenerate_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
WebAuthn.parse_assertion
— Methodparse_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
.
WebAuthn.parse_attestation_object
— Methodparse_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
.
WebAuthn.parse_clientdata_json
— Methodparse_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
.
WebAuthn.parse_credential_public_key
— Methodparse_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
.
WebAuthn.parse_ec_pem_xy
— Methodparse_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
.
WebAuthn.parse_ed25519_pem_x
— Methodparse_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
.
WebAuthn.parse_rsa_pem_ne
— Methodparse_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
.
WebAuthn.pem_to_der
— Methodpem_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);
WebAuthn.registration_options
— Methodregistration_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
.
WebAuthn.verify_attestation_object
— Methodverify_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
.
WebAuthn.verify_attestation_packed
— Methodverify_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
WebAuthn.verify_challenge
— Methodverify_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
WebAuthn.verify_p256_signature_raw_xy
— Methodverify_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
WebAuthn.verify_rsa_signature_raw_ne
— Methodverify_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
WebAuthn.verify_webauthn_signature
— Functionverify_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
.
WebAuthn.verify_webauthn_signature
— MethodAvoid this too?