1. 詳細
1.1. クレデンシャル情報の表現
クレデンシャル情報を表現するインタフェースとして、 CredentialRecord
インタフェースが存在します。 登録時に、 RegistrationData
クラスが含む値を用いて CredentialRecord
インタフェースの インスタンスを作成し、アプリケーションの作法に則り永続化してください。認証時の検証に必要となります。 なお、永続化する際は、検索する際の利便性を考え、credentialIdをキーに永続化すると良いでしょう。
CredentialRecord
インタフェースの実装クラスを設計する際は、アプリケーションの要件に合わせて拡張すると良いでしょう。 典型的には、 CredentialRecord
をユーザーが識別するための名前フィールドの追加などが考えられるでしょう。
1.2. CredentialRecordのシリアライズ、デシリアライズ
認証デバイスの登録時、CredentialRecord
のインスタンスをデータベース等に永続化し、認証時に利用できるようにするのはアプリケーションの責務ですが、
CredentialRecord
を構成する各メンバをシリアライズ、デシリアライズする際に使用できるクラスをWebAuthn4Jでは用意しています。 アプリケーションで永続化を実装する際の補助としてご利用ください。
1.2.1. attestedCredentialData
AttestedCredentialDataConverter
で AttestedCredentialData
を byte[]
に変換したり、その逆の変換を行うことが出来ます。 なお、String
として保存したい場合、さらに Base64UrlUtil
を用いることで byte[]
から Base64Url String
に変換することが出来ます。
AttestedCredentialDataConverter attestedCredentialDataConverter = new AttestedCredentialDataConverter(objectConverter);
// serialize
byte[] serialized = attestedCredentialDataConverter.convert(attestedCredentialData);
// deserialize
AttestedCredentialData deserialized = attestedCredentialDataConverter.convert(serialized);
1.2.2. attestationStatement
AttestationStatement
はインタフェースであり、PackedAttestationStatement
や、AndroidKeyAttestationStatement
など、フォーマットにあわせて複数の実装があります。
AttestationStatement
のCBOR表現は具象型が何であるかについて自己記述性を持たない為、フォーマットは別途、別のフィールドとして永続化する必要があります。 そのため、CBORとしてシリアライズする際は、実際のattestationStatementのフィールドと、フォーマットのフィールドを持つエンベロープクラスを用意し、エンベロープクラスをシリアライズしなければなりません。
//serialize
AttestationStatementEnvelope envelope = new AttestationStatementEnvelope(attestationStatement);
byte[] serializedEnvelope = objectConverter.getCborConverter().writeValueAsBytes(envelope);
//deserialize
AttestationStatementEnvelope deserializedEnvelope = objectConverter.getCborConverter().readValue(serializedEnvelope, AttestationStatementEnvelope.class);
AttestationStatement deserializedAttestationStatement = deserializedEnvelope.getAttestationStatement();
class AttestationStatementEnvelope{
@JsonProperty("attStmt")
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
property = "fmt"
)
private AttestationStatement attestationStatement;
@JsonCreator
public AttestationStatementEnvelope(@JsonProperty("attStmt") AttestationStatement attestationStatement) {
this.attestationStatement = attestationStatement;
}
@JsonProperty("fmt")
public String getFormat() {
return attestationStatement.getFormat();
}
public AttestationStatement getAttestationStatement() {
return attestationStatement;
}
}
1.2.3. transports
JSON文字列として保存したい場合は ObjectConverter
が使用できます。
String serializedTransports = objectConverter.getJsonConverter().writeValueAsString(transports);
1.3. DCAppleDeviceのシリアライズ、デシリアライズ
webauthn4j-device-checkでは、CredentialRecord
インタフェースの代わりに、DCAppleDevice
インタフェースを実装したクラスを、構成証明の検証時とアサーションの検証時の間で永続化する必要があります。 概ねCredentialRecordのシリアライズ、デシリアライズで解説した方法でシリアライズ、デシリアライズが可能ですが、一点気を付ける必要がある点として、 webauthn4j-device-check独自のクラス(例えば AppleAppAttestAttestationStatement
)のシリアライズ、デシリアライズを行う為に、
ObjectConverter
は DeviceCheckCBORModule
が登録されたものを使用する必要があります。
DeviceCheckCBORModule
が登録された`ObjectConverter` は DeviceCheckManager#createObjectConverter
で得ることが出来ます。
1.4. WebAuthn以外のFIDO CTAP2セキュリティキーを用いた独自アプリケーションでの利用
FIDO CTAP2セキュリティキーにとって、WebAuthnは一つの応用例でしかなく、セキュアな認証を必要とする独自アプリケーションで セキュリティキーを利用することも可能です。本節では、FIDO CTAP2セキュリティキーを用いた独自アプリケーションにおけるAttestation、Assertion検証でWebAuthn4Jを利用する方法を説明します。
1.4.1. FIDO CTAP2セキュリティキーを用いた独自アプリケーションでの登録、認証のフロー
FIDO CTAP2セキュリティキーを独自アプリケーションで認証に使用する場合、セキュリティキーを登録するために、 アプリからFIDO CTAP2セキュリティキーの authenticatorMakeCredential メソッドを呼び出し、公開鍵やデバイスの構成情報を 含むデータ(構成証明、Attestation)を取得し保存します。 取得されたAttestationは、セキュリティキーがアプリとして受け入れ可能なキーか判定するために検証が必要です。 WebAuthn4Jでは、 CoreRegistrationVerifier
クラスを用いることで、取得されたAttestationを検証可能です。
認証時には、同様にアプリからFIDO CTAP2セキュリティキーの authenticatorGetAssertion メソッドを呼び出し、認証時にサーバーに送信される署名を含んだデータ(アサーション、Assertion)を取得します。 取得されたAssertionを検証することで、アプリは認証に用いられたセキュリティキーが、登録時に用いられたセキュリティキーと同一であることを確認し、正当なアクセスか判定することが可能となります。WebAuthn4Jでは、 CoreAuthenticationVerifier
クラスを用いることで、取得されたAssertionを検証可能です。
1.4.2. アプリケーション固有のクライアントデータの真正性の担保、検証
上記のフローに従って実装することで、FIDO CTAP2セキュリティキーを用いた安全な認証が実現可能ですが、 FIDO CTAP2セキュリティキーを呼び出す主体(クライアント)と、Attestation、Assertionを検証する主体(サーバー)が分離している場合、クライアントが登録、認証時にアプリケーション固有のクライアントデータを生成し、クライアントデータを追加でサーバーで検証したい場合もあります。クライアントデータ自体はAttestation、Assertionと一緒に送信すれば良いですが、 クライアントデータを中間者攻撃から防御するために、クライアントデータに対して署名を行い、保護する必要があります。
さて、FIDO CTAP2では、登録時に利用する authenticatorMakeCredential メソッドと認証時に利用する authenticatorGetAssertion メソッド 、どちらにも共通するパラメータとして、clientDataHash
というパラメータが存在します。セキュリティキーは、受け取った clientDataHash
パラメータを署名対象のデータの一部として署名を生成するため、アプリケーションとして署名で保護したいクライアントデータのハッシュを取得し、
clientDataHash
にセットすることで、アプリケーション固有のクライアントデータが改竄されていない真正なデータか、サーバー側で検証することが出来ます。
1.5. Project Modules
WebAuthn4Jは、以下の4つのModuleから構成されます。
1.5.3. Core-Async: webauthn4j-core-async.jar
WebAuthn Attestation/Assertionの検証機能およびコア機能の非同期版を提供します。現時点では、実験的な提供です。 含まれているクラスは、Publicであっても、セマンティックバージョニングに従わずに破壊的変更が入る場合があります。
1.5.4. Metadata-Async: webauthn4j-metadata-async.jar
FIDO Metadata Serviceを用いたTrustAnchorの解決など、追加的な機能の非同期バージョンを提供します。 現時点では、実験的な提供です。 含まれているクラスは、Publicであっても、セマンティックバージョニングに従わずに破壊的変更が入る場合があります。
1.6. カスタムなデータ変換ロジックの実装
WebAuthn4Jでは、JSONやCBORのシリアライズ、デシリアライズ処理にJacksonライブラリを使用しています。 Client ExtensionやAuthenticator Extensionのデータ変換でカスタムな変換を行いたい場合、WebAuthn4Jが内部で使用している Jacksonの ObjectMapper
にカスタムなシリアライザ、デシリアライザを登録することで実現できます。
1.7. カスタムな検証ロジックの実装
WebAuthn4Jでは、カスタムな検証ロジックを実装し、追加することが可能です。 登録時の検証にカスタムロジックを追加する場合は、 CustomRegistrationVerifier
を実装してください。 認証時の検証にカスタムロジックを追加する場合は、 CustomAuthenticationVerifier
を実装してください。
1.8. クラス
1.8.2. Converter, WebAuthnModule
データパッケージ配下のクラスはJacksonによってシリアライズ、デシリアライズ可能なように設計されています。 一部のクラスはカスタムなシリアライザ、デシリアライザが必要であり、 converter
パッケージ配下に集約されています。 カスタムシリアライザ、デシリアライザは WebAuthnJSONModule
と WebAuthnCBORModule
というJacksonのModuleにまとめられています。 WebAuthn4Jは内部で使用するJacksonの ObjectMapper
に自動で WebAuthnModule
を適用しますが、WebAuthnManager
の外部で WebAuthn4Jのシリアライザ、デシリアライザを使用したい場合は、Jacksonの ObjectMapper
に WebAuthnModule
を登録すると 良いでしょう。
1.8.3. TrustAnchorsResolver
TrustAnchorsResolver
インタフェースは TrustAnchorCertPathTrustworthinessVerifier
で構成証明ステートメントの信頼性の 検証を行う際に信頼するルート証明書のセットを探索するために使用されます。
1.8.4. TrustAnchorsProvider
TrustAnchorsProvider
インタフェースは前述の TrustAnchorsResolver
インタフェースの実装である TrustAnchorsResolverImpl
がTrustAnchorの読込処理を委譲する先のインタフェースです。実装としてJava Key StoreファイルからTrustAnchorを読み込む
KeyStoreFileTrustAnchorsProvider
クラスが提供されている他、WebAuthn4J Spring Securityでは、SpringのResourceから TrustAnchorを読み込む CertFileResourcesTrustAnchorProvider
が提供されています。