7 Ağustos 2021 Cumartesi

Web Authentication Standard

Giriş
Çoğu tarayıcı da artık var. Açıklaması şöyle
Long story short, with WebAuthentication you can authenticate in an application without sending your password to any remote server by using either your OS credentials, fingerprint or face recognition etc.
Nasıl Çalışır
Açıklaması şöyle
... it works by generating a site-specific private key and storing that key somewhere on the user's device. Then, when the user wants to sign into a site, their browser uses this stored key to prove the user's identity to the site using public key authentication, signing them in.

So where do biometrics come into this? Using the web authentication standard, it is possible for websites to request that the user's browser verify their identity locally before allowing them to sign-in using the stored public key. This local verification can be done using biometrics, among other methods.
Biometric Olarak Ne Kullanılabilir
Biometric veriyi tanımlarken "something you are" ifadesi kullanılıyor. Bu ifadenin açıklaması şöyle
"Something you are" refers to biometric identification. Examples of this could include:
- fingerprint
- voice print
- facial recognition
- vein pattern and blood flow detection
- behavioral biometrics, such as gait or typing timing

This is described in NIST SP 800-63B section 5.2.3 which does not list specific methods, but describes requirements and how to use them.

Section 10.4 lists usability considerations of these specific biometrics, including problems with their reliability:
- Fingerprints
- Face
- Iris
Yani Biometric Veri Sunucuya Gönderilmez
Açıklaması şöyle
The user never authenticates to the internet service with biometrics. Instead, the user authenticates to a local device (fingerprint reader, mobile phone, ...), and then that device authenticates to the service. The service trusts the device to perform the user authentication.

Notice how the service never receives the biometrics themselves - so they can't be leaked through a service or database compromise.
Örnek
Bu işi anlatan örnek  yazı burada. Kaynak kodu burada. Aslında işin temelini yapan kütüphaneler şöyle
<dependency> <groupId>com.yubico</groupId> <artifactId>webauthn-server-core</artifactId> <version>1.7.0</version> <exclusions> <exclusion> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.yubico</groupId> <artifactId>yubico-util</artifactId> <version>1.7.0</version> </dependency>
Repository Sınıfları
User şöyledir ve haliyle bir UserRepository vardır
public class WebAuthnUser implements UserDetails {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  private String username;
  private byte[] recoveryToken;
  private byte[] addToken;
  private LocalDateTime registrationAddStart;
  ...
}
Credentials şöyledir. Bu ilgili kullanıcının credentials bilgisidir.
public class WebAuthnCredentials {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  private byte[] credentialId;
  private Long appUserId;
  private Long count;
  private byte[] publicKeyCose;
  private String userAgent;
  ...
}
Registration Start
Burada sadece tarayıcı aslında sadece username'i göndermek zorunda. Diğer alanlar registration başladıktan sonra eğer istenirse yeni token eklemek için kullanılabiliyor. İşlemin sonucunda bir
WebAuthnUser yaratılır. Gelen istek şöyle
public class RegistrationStartRequest {

  private String username;
  private String registrationAddToken;
  private String recoveryToken;
  ...
}
JSON olarak şöyle
{"username":"newjunit","registrationAddToken":null,"recoveryToken":null}
Döndürülen cevap şöyle
public class RegistrationStartResponse {

  public enum Status {
    OK, USERNAME_TAKEN, TOKEN_INVALID
  }

  public enum Mode {
    NEW, ADD, RECOVERY
  }

  @JsonIgnore
  private final Mode mode;

  private final Status status;

  private final String registrationId;
  
  //RelyingPartyIdentity + UserIdentity + challenge
  private final PublicKeyCredentialCreationOptions publicKeyCredentialCreationOptions;
  ...
}
JSON olarak şöyle
{
  "status": "OK",
  "registrationId": "Ey6LyiaXLwgM8wxeNIXnKQ==",
  "publicKeyCredentialCreationOptions": {
    "rp": {
      "name": "localhost",
      "id": "localhost",
      "icon": {
        "empty": false,
        "present": true
      }
    },
    "user": {
      "name": "newjunit",
      "displayName": "newjunit",
      "id": "AAAAAAAAAAM",
      "icon": {
        "empty": true,
        "present": false
      }
    },
    "challenge": "hZV-7roGRNnDzytShOxyDAvVTAHQTcVamfr2TYmDJZg",
    "pubKeyCredParams": [
      {
        "alg": -7,
        "type": "public-key"
      },
      {
        "alg": -8,
        "type": "public-key"
      },
      {
        "alg": -257,
        "type": "public-key"
      }
    ],
    "timeout": {
      "empty": true,
      "present": false
    },
    "excludeCredentials": {
      "empty": false,
      "present": true
    },
    "authenticatorSelection": {
      "empty": true,
      "present": false
    },
    "attestation": "none",
    "extensions": {}
  }
}
Registration Finish
Gelen istek şöyle
public class RegistrationFinishRequest {

  private final String registrationId;
  private String userAgent;
  
  //Signed credential
  private PublicKeyCredential<AuthenticatorAttestationResponse,
    ClientRegistrationExtensionOutputs> credential;
}
Registration Repository'den registrationId ile nesne bulunur. Doğrulama yapılır ve WebAuthnCredentials nesnesi kaydedilir. 

Assertion Start ve Assertion End
Doğrulama yapılır







Hiç yorum yok:

Yorum Gönder