安全上下文
此特征只可用于
安全上下文
(HTTPS),在某些或所有
支持浏览器
.
The Web Authentication API is an extension of the 证书管理 API that enables strong authentication with public key cryptography, enabling passwordless authentication and/or secure second-factor authentication without SMS texts.
The Web Authentication API (also referred to as WebAuthn) uses asymmetric (public-key) cryptography instead of passwords or SMS texts for registering, authenticating, and second-factor authentication with websites. This resolves significant security problems related to phishing , data breaches , and attacks against SMS texts or other second-factor authentication methods while at the same time significantly increasing ease of use (since users don't have to manage dozens of increasingly complicated passwords).
Many websites already have pages that allow users to register new accounts or sign in to an existing account, and the Web Authentication API acts as a replacement or supplement to those on those existing webpages. Similar to the other forms of the 证书管理 API , the Web Authentication API has two basic methods that correspond to register and login:
navigator.credentials.create()
- when used with the publicKey option, creates new credentials, either for registering a new account or for associating a new asymmetric key pair credentials with an existing account.
navigator.credentials.get()
- when used with the publicKey option, uses an existing set of credentials to authenticate to a service, either logging a user in or as a form of second-factor authentication.
请注意: both create() and get() require a Secure Context (e.g. - the server is connected by https or is the localhost), and will not be available for use if the browser is not operating in a secure context.
In their most basic forms, both create() and get() receive a very large random number called a challenge from the server and they return the challenge signed by the private key back to the server. This proves to the server that a user is in possession of the private key required for authentication without revealing any secrets over the network.
In order to understand how the create() and get() methods fit into the bigger picture, it is important to understand that they sit between two components that are outside the browser:
A typical registration process has six steps, as illustrated in Figure 1 and described further below. This is a simplification of the data required for the registration process that is only intended to provide an overview. The full set of required fields, optional fields, and their meanings for creating a registration request can be found in the
PublicKeyCredentialCreationOptions
dictionary. Likewise, the full set of response fields can be found in the
PublicKeyCredential
interface (where
PublicKeyCredential.response
是
AuthenticatorAttestationResponse
interface). Note most JavaScript programmers that are creating an application will only really care about steps 1 and 5 where the create() function is called and subsequently returns; however, steps 2, 3, and 4 are essential to understanding the processing that takes place in the browser and authenticator and what the resulting data means.
Figure 1 - a diagram showing the sequence of actions for a web authentication registration and the essential data associated with each action.
The registration steps are:
PublicKeyCredential
containing an
AuthenticatorAttestationResponse
.
Note that it is absolutely critical that the challenge be a buffer of random information (at least 16 bytes) and it MUST be generated on the server in order to ensure the security of the registration process.
AuthenticatorResponse.clientDataJSON
. One of the most important parameters is the origin, which is recorded as part of the clientData so that the origin can be verified by the server later. The parameters to the create() call are passed to the authenticator, along with a SHA-256 hash of the clientDataJSON (only a hash is sent because the link to the authenticator may be a low-bandwidth NFC or Bluetooth link and the authenticator is just going to sign over the hash to ensure that it isn't tampered with).
PublicKeyCredential
, which has a
PublicKeyCredential.rawId
that is the globally unique credential id along with a response that is the
AuthenticatorAttestationResponse
containing the
AuthenticatorResponse.clientDataJSON
and
AuthenticatorAttestationResponse.attestationObject
。
PublicKeyCredential
is sent back to the server using any desired formatting and protocol (note that the ArrayBuffer properties need to be be base64 encoded or similar).
After a user has registered with web authentication, they can subsequently authenticate (a.k.a. - login or sign-in) with the service. The authentication flow looks similar to the registration flow, and the illustration of actions in Figure 2 may be recognizable as being similar to the illustration of registration actions in Figure 1. The primary differences between registration and authentication are that: 1) authentication doesn't require user or relying party information; and 2) authentication creates an assertion using the previously generated key pair for the service rather than creating an attestation with the key pair that was burned into the authenticator during manufacturing. Again, the description of authentication below is a broad overview rather than getting into all the options and features of the Web Authentication API. The specific options for authenticating can be found in the
PublicKeyCredentialRequestOptions
dictionary, and the resulting data can be found in the
PublicKeyCredential
interface (where
PublicKeyCredential.response
是
AuthenticatorAssertionResponse
interface).
Figure 2 - similar to Figure 1, a diagram showing the sequence of actions for a web authentication and the essential data associated with each action.
AuthenticatorResponse.clientDataJSON
. One of the most important parameters is the origin, which recorded as part of the clientData so that the origin can be verified by the server later. The parameters to the get() call are passed to the authenticator, along with a SHA-256 hash of the clientDataJSON (only a hash is sent because the link to the authenticator may be a low-bandwidth NFC or Bluetooth link and the authenticator is just going to sign over the hash to ensure that it isn't tampered with).
PublicKeyCredential
采用
PublicKeyCredential.response
包含
AuthenticatorAssertionResponse
. It is up to the JavaScript application to transmit this data back to the server using any protocol and format of its choice.
Credential
Provides information about an entity as a prerequisite to a trust decision.
CredentialsContainer
Navigator.credentials
. The Web Authentication specification adds a
publicKey
member to the
create()
and
get()
methods to either create a new public key pair or get an authentication for a key pair, repsectively.
PublicKeyCredential
Provides information about a public key / private key pair, which is a credential for logging in to a service using an un-phishable and data-breach resistant asymmetric key pair instead of a password.
AuthenticatorResponse
AuthenticatorAttestationResponse
and
AuthenticatorAssertionResponse
, which provide a cryptographic root of trust for a key pair. Returned by
CredentialsContainer.create()
and
CredentialsContainer.get()
, respectively, the child interfaces include information from the browser such as the challenge origin. Either may be returned from
PublicKeyCredential.response
.
AuthenticatorAttestationResponse
CredentialsContainer.create()
当
PublicKeyCredential
is passed, and provides a cryptographic root of trust for the new key pair that has been generated.
AuthenticatorAssertionResponse
CredentialsContainer.get()
当
PublicKeyCredential
is passed, and provides proof to a service that it has a key pair and that the authentication request is valid and approved.
PublicKeyCredentialCreationOptions
CredentialsContainer.create()
.
PublicKeyCredentialRequestOptions
CredentialsContainer.get()
.
For security reasons, web authentication calls (
create()
and
get()
) are cancelled if the browser window loses focus while the call is pending.
// sample arguments for registration
var createCredentialDefaultArgs = {
publicKey: {
// Relying Party (a.k.a. - Service):
rp: {
name: "Acme"
},
// User:
user: {
id: new Uint8Array(16),
name: "john.p.smith@example.com",
displayName: "John P. Smith"
},
pubKeyCredParams: [{
type: "public-key",
alg: -7
}],
attestation: "direct",
timeout: 60000,
challenge: new Uint8Array([ // must be a cryptographically random number sent from a server
0x8C, 0x0A, 0x26, 0xFF, 0x22, 0x91, 0xC1, 0xE9, 0xB9, 0x4E, 0x2E, 0x17, 0x1A, 0x98, 0x6A, 0x73,
0x71, 0x9D, 0x43, 0x48, 0xD5, 0xA7, 0x6A, 0x15, 0x7E, 0x38, 0x94, 0x52, 0x77, 0x97, 0x0F, 0xEF
]).buffer
}
};
// sample arguments for login
var getCredentialDefaultArgs = {
publicKey: {
timeout: 60000,
// allowCredentials: [newCredential] // see below
challenge: new Uint8Array([ // must be a cryptographically random number sent from a server
0x79, 0x50, 0x68, 0x71, 0xDA, 0xEE, 0xEE, 0xB9, 0x94, 0xC3, 0xC2, 0x15, 0x67, 0x65, 0x26, 0x22,
0xE3, 0xF3, 0xAB, 0x3B, 0x78, 0x2E, 0xD5, 0x6F, 0x81, 0x26, 0xE2, 0xA6, 0x01, 0x7D, 0x74, 0x50
]).buffer
},
};
// register / create a new credential
navigator.credentials.create(createCredentialDefaultArgs)
.then((cred) => {
console.log("NEW CREDENTIAL", cred);
// normally the credential IDs available for an account would come from a server
// but we can just copy them from above...
var idList = [{
id: cred.rawId,
transports: ["usb", "nfc", "ble"],
type: "public-key"
}];
getCredentialDefaultArgs.publicKey.allowCredentials = idList;
return navigator.credentials.get(getCredentialDefaultArgs);
})
.then((assertion) => {
console.log("ASSERTION", assertion);
})
.catch((err) => {
console.log("ERROR", err);
});
| 规范 | 状态 | 注释 |
|---|---|---|
| Web Authentication: An API for accessing Public Key Credentials Level 1 | 推荐 | 初始定义。 |
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
Credential
|
Chrome 51 | Edge 18 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 51 | Chrome Android 51 | Firefox Android Yes | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android 5.0 |
id
|
Chrome 51 | Edge 18 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 51 | Chrome Android 51 | Firefox Android Yes | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android 5.0 |
名称
(from
CredentialUserData
mixin)
|
Chrome
51 — 52
|
Edge ? | Firefox No | IE ? | Opera ? | Safari ? |
WebView Android
51 — 52
|
Chrome Android
51 — 52
|
Firefox Android No | Opera Android ? | Safari iOS ? |
Samsung Internet Android
5.0 — 6.0
|
type
|
Chrome 51 | Edge 18 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 51 | Chrome Android 51 | Firefox Android Yes | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android 5.0 |
完整支持
不支持
兼容性未知
实验。期望将来行为有所改变。
见实现注意事项。
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
CredentialsContainer
|
Chrome 51 | Edge 18 | Firefox Yes | IE ? | Opera No | Safari 13 | WebView Android 51 | Chrome Android 51 | Firefox Android Yes | Opera Android No | Safari iOS 13.3 | Samsung Internet Android 5.0 |
create
|
Chrome 60 | Edge 18 | Firefox Yes | IE ? | Opera No | Safari 13 | WebView Android 60 | Chrome Android 60 | Firefox Android Yes | Opera Android No | Safari iOS 13.3 | Samsung Internet Android 8.0 |
get
|
Chrome 51 | Edge 18 | Firefox Yes | IE ? | Opera No | Safari 13 | WebView Android 51 | Chrome Android 51 | Firefox Android Yes | Opera Android No | Safari iOS 13.3 | Samsung Internet Android 5.0 |
preventSilentAccess
|
Chrome
60
|
Edge ≤79 | Firefox Yes | IE ? | Opera No | Safari ? |
WebView Android
60
|
Chrome Android
60
|
Firefox Android Yes | Opera Android No | Safari iOS ? |
Samsung Internet Android
8.0
|
store
|
Chrome 51 | Edge ≤79 | Firefox Yes | IE ? | Opera No | Safari ? | WebView Android 51 | Chrome Android 51 | Firefox Android Yes | Opera Android No | Safari iOS ? | Samsung Internet Android 5.0 |
完整支持
不支持
兼容性未知
实验。期望将来行为有所改变。
使用非标名称。
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
PublicKeyCredential
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
getClientExtensionResults
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
isUserVerifyingPlatformAuthenticatorAvailable
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
rawId
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
response
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
完整支持
不支持
见实现注意事项。
用户必须明确启用此特征。
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
AuthenticatorResponse
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
clientDataJSON
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
完整支持
不支持
见实现注意事项。
用户必须明确启用此特征。
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
AuthenticatorAttestationResponse
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android 10.0 |
attestationObject
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android 10.0 |
getTransports
|
Chrome No | Edge No | Firefox No | IE No | Opera No | Safari No | WebView Android No | Chrome Android No | Firefox Android No | Opera Android No | Safari iOS No | Samsung Internet Android No |
完整支持
不支持
实验。期望将来行为有所改变。
见实现注意事项。
用户必须明确启用此特征。
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
AuthenticatorAssertionResponse
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
authenticatorData
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
signature
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
userHandle
|
Chrome
67
|
Edge 18 |
Firefox
60
|
IE No | Opera No | Safari 13 | WebView Android 70 | Chrome Android 70 |
Firefox Android
60
|
Opera Android No | Safari iOS 13.3 | Samsung Internet Android No |
完整支持
不支持
见实现注意事项。
用户必须明确启用此特征。
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
PublicKeyCredentialCreationOptions
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
attestation
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera ? | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android No |
authenticatorSelection
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera ? | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android No |
challenge
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera ? | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android No |
excludeCredentials
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera ? | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android No |
extensions
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera ? | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android No |
pubKeyCredParams
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera ? | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android No |
rp
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
timeout
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera ? | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android No |
user
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera ? | Safari 13 | WebView Android No | Chrome Android 67 | Firefox Android ? | Opera Android ? | Safari iOS 13.3 | Samsung Internet Android No |
完整支持
不支持
兼容性未知
实验。期望将来行为有所改变。
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
PublicKeyCredentialRequestOptions
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 67 | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
allowCredentials
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 67 | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
challenge
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 67 | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
extensions
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 67 | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
rpId
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 67 | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
timeout
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 67 | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
userVerification
|
Chrome 67 | Edge ≤79 | Firefox 60 | IE ? | Opera Yes | Safari 13 | WebView Android 67 | Chrome Android 67 | Firefox Android ? | Opera Android Yes | Safari iOS 13.3 | Samsung Internet Android No |
完整支持
不支持
兼容性未知
实验。期望将来行为有所改变。