비밀번호 없는 세상

우리는 현실에 직면하게 된다. 요 며칠 동안 비밀번호가 없으면 살 수 없다.사실 우리의 전체 인터넷 생활은 모두 그들에게 의존한다.그러나 비밀번호가 등장하면서 사용자뿐만 아니라 우리 개발자들에게도 많은 문제가 생길 수 있다.

고통스러운 사실


대부분의 사람들은 자신이 속한 많은 사이트에 사용할 약한 비밀번호를 가지고 있다.소셜 미디어, 전자메일, 생산력 도구 등은 모두 다른 암호 정책을 가지고 있으며, 대다수 사용자들은 약한 암호나 댓글에 쓴 강한 암호를 사용하여 그것을 우회하는 방법을 찾을 수 있다🤷🏽‍♂️.
사실 데이터 유출의 81%는 해커 공격으로 인한 것이다leverage stolen or weak passwords.

더 좋은 방법이 있어요.


그러나 W3CFIDO의 거대한 노력 덕분에 우리는 반드시 모든 일에 비밀번호를 사용해야 하는 것은 아니다.웹 인증 API,akaWebAuthn는 공평한new specification으로 새로운 암호 없는 인증 방법을 도입하고 암호와 함께 사용한다.
구글, 마이크로소프트, 유비코와 다른 업계 유명 인사들은 모두 이 규범이 널리 전파된 공헌자이다.이 API를 사용하면 서버에서 암호 대신 공개 키 암호화를 사용하여 사용자를 등록하고 인증할 수 있습니다.
Windows Hello, Apple의 Touch ID, Yubikey 장치는 암호가 필요 없는 다양한 유형의 인증 메커니즘의 예입니다.그들은 생물적 특징이나 하드웨어 설비를 사용하여 이 점을 실현한다.

작업 원리


1000피트부터 비밀번호가 아닌 사이트를 위한 key pair (public and private) 를 사용할 것입니다.
개인 키는 사용자의 장치에 안전하게 저장되고, 공개 키와 무작위로 생성된 인증서 ID는 웹 서버에 전송되어 저장되며, 나중에 특정 사용자를 검증하는 데 사용됩니다.
일반적으로 WebAuthn은 세 가지 주요 측면에 의존합니다.
  • 인증기(인증 및 검증 중인 장치)
  • 의존자(웹 응용 프로그램 소유자)
  • 브라우저의 웹 인증 API
  • 절차가 상당히 간단하다. 첫 번째 단계는 등록이고, 그 다음은 신분 검증이다.

    등록 자격 증명


    암호 인증 절차와 마찬가지로 웹 서버는 일반적으로 사용자가 암호를 입력하고 서버에 전송하여 검증할 수 있도록 폼을 제공한다.
    WebAuthn의 경우, 이것은 상당히 유사하지만, 의존자는 암호를 요구하는 것이 아니라 공개 키를 요구한다.

    WebAuthn의 이미지입니다.io
    자격 증명을 입력하라는 메시지가 표시될 때 사용navigator.credentials.create():
    const credential = await navigator.credentials.create(
      {
        publicKey: publicKeyCredentialCreationOptions,
      }
    )
    
    publicKeyCredentialCreationOptions 에 대해 알고 싶으면 다음과 같은 필수 필드와 선택 가능한 필드를 포함합니다.
    const publicKeyCredentialCreationOptions = {
      challenge: Uint8Array.from(
        randomStringFromServer,
        c => c.charCodeAt(0)
      ),
      rp: {
        name: 'Google',
        id: 'accounts.google.com',
      },
      user: {
        id: Uint8Array.from('5T9AFCUZSL8', c =>
          c.charCodeAt(0)
        ),
        name: '[email protected]',
        displayName: 'Yaser',
      },
      pubKeyCredParams: [
        { alg: -7, type: 'public-key' },
      ],
      authenticatorSelection: {
        authenticatorAttachment: 'cross-platform',
      },
      timeout: 60000,
      attestation: 'direct',
    }
    
    challenge: 옵션에서 가장 중요한 부분은 도전입니다.이것은 서버에서 무작위로 생성된 바이트로 공격 회답을 방지하는 데 쓰인다.rp: 의존자를 표시하고 사용자가 등록하려고 하는 웹 서버입니다.user: 서비스에 등록된 최종 사용자입니다.id 공개 키를 이 사용자와 연결하는 데 사용하지만 개인 식별 정보는 사용하지 않는 것을 권장합니다.pubKeyCredPrams: 서버에서 사용할 수 있는 공개 키를 지정합니다.authenticatorSelection: 등록할 수 있는 검증기에 대한 의존자의 제한을 돕는 선택 가능한 필드입니다.Windows Hello 또는 Yubikey 등의 가능한 값platform을 찾을 수 있습니다.cross-platform: 사용자가 등록 프롬프트에 응답해야 하는 시간(ms)입니다.timeout: 이것은 인증기에서 되돌아온 것으로 사용자 추적에 사용할 수 있는 정보를 포함합니다.그것은 이번 등록 활동에 대한 인증의 중요성을 나타냈다.예를 들어, attestation 를 사용하는 경우 서버가 해당 서버에 관심을 갖지 않음을 나타냅니다.none 서버에서 익명으로 데이터를 인증할 수 있음을 나타냅니다.indirect 서버가 인증기에서 데이터를 필요로 한다는 것을 나타낸다.일반적으로 이것은 등록할 때 사용자의 프라이버시에 관한 것이다.direct 호출에서 반환된 객체는 공개 키와 사용자의 다른 속성을 검증하는 데 사용됩니다.
    console.log(credential);
    
    PublicKeyCredential {
        id: 'ADSUllKQmbqdGtpu4sjseh4cg2TxSvrbcHDTBsv4NSSX9...',
        rawId: ArrayBuffer(59),
        response: AuthenticatorAttestationResponse {
            clientDataJSON: ArrayBuffer(121),
            attestationObject: ArrayBuffer(306),
        },
        type: 'public-key'
    }
    

    규격상 의존자 가 등록 데이터 를 검증 하다


    공개 키가 등록 데이터의 다른 속성과 함께 서버에 수신되면 이 데이터를 검증합니다.
    물론 실현은 당신이 사용하는 언어에 달려 있지만, 이러한 절차를 어떻게 실현하는지 알고 싶다면 예를 들 수 있습니다.Duo 실험실은there is a procedureGo에서 완전한 실현을 제공했다.

    구렁이 WebAuthn을 사용하여 인증


    등록이 완료되면 사용자는 사이트에 대한 인증을 할 수 있습니다.등록 기간 동안 사용자는 개인 키를 가지고 있다는 단언을 얻었다.여기에는 상술한 개인 키를 사용한 서명이 포함되어 있습니다.웹 서버는 등록하는 동안 이 점을 검증하기 위해 공개 키를 사용합니다.
    인증 흐름은 다음과 같습니다.

    WebAuthn의 이미지입니다.io
    사용자가 개인 키를 가지고 있다는 것을 증명하기 위해 create() 방법을 호출합니다.이것은 등록 기간에 생성된 증명서를 검색합니다. 서명이 포함되어 있습니다.
    const credential = await navigator.credentials.get(
      {
        publicKey: publicKeyCredentialRequestOptions,
      }
    )
    
    navigator.credentials.get() 객체에는 서버에서 지정한 많은 강제 및 옵션 속성이 포함되어 있습니다.
    const publicKeyCredentialRequestOptions = {
      challenge: Uint8Array.from(
        randomStringFromServer,
        c => c.charCodeAt(0)
      ),
      allowCredentials: [
        {
          id: Uint8Array.from(credentialId, c =>
            c.charCodeAt(0)
          ),
          type: 'public-key',
          transports: ['usb', 'ble', 'nfc'],
        },
      ],
      timeout: 60000,
    }
    
    이 대상 중 가장 재미있는 부분은 전송 속성이다.서버는 USB, NFC, Bluetooth 등 원하는 전송 방식을 선택적으로 표시할 수 있습니다.
    반환된 객체는 publicKeyCredentialRequestOptions 객체이지만 이전 등록 객체와는 약간 다릅니다.
    console.log(assertion);
    
    PublicKeyCredential {
        id: 'SSX9lKQmbqdGtbcHDTBsvpu4sjseh4cg2TxSvr4ADSUlN...',
        rawId: ArrayBuffer(59),
        response: AuthenticatorAssertionResponse {
            authenticatorData: ArrayBuffer(191),
            clientDataJSON: ArrayBuffer(118),
            signature: ArrayBuffer(70),
            userHandle: ArrayBuffer(10),
        },
        type: 'public-key'
    }
    
    이 객체에 대한 추가 정보 .

    참조 사양 인증 데이터 확인


    단언을 가져오면 서버에 보내 검증합니다.인증 후 저장된 공개 키를 사용하여 서명을 검증합니다.
    const storedCredential = await getCredentialFromDatabase(
      userHandle,
      credentialId
    )
    
    const signedData =
      authenticatorDataBytes + hashedClientDataJSON
    
    const signatureIsValid = storedCredential.publicKey.verify(
      signature,
      signedData
    )
    
    if (signatureIsValid) {
      return 'Hooray! User is authenticated! 🎉'
    } else {
      return 'Verification failed. 😭'
    }
    

    추가 읽기 및 리소스


    다음 리소스는 더 나은 읽기의 시작점입니다.

  • : Due 실험실은 이 유용한 자원을 만들었는데 모든 원본 코드와 예시 용례를 포함하고 아름다운 삽화를 첨부했다.

  • Webauthn.io: 내용이 풍부한 블로그 문장으로 진전을 소개하고 모든 주요 브라우저와 공헌자의 이 분야에서의 호환성을 보여준다.

  • Developments to WebAuthn and the FIDO2 Framework: 이 GitHub repo는 실험실에서 이 기능을 보여주기 위해 만든 모든 소스 코드를 포함하고 있습니다.
  • 인터넷의 큰 날: Source Code

  • W3C Standardizes WebAuthn: 엔드 유저 관점에서 프로세스 프레젠테이션
  • 유비코 프레젠테이션 사이트 총결산


    우리는 이 놀라운 기능을 실현하는 것이 얼마나 간단하고 직접적인지 보았다. 만약에 녹지 프로젝트에 종사하고 있다면 반드시 이 기능을 실현하여 사용자가 암호 없이 생활할 수 있도록 고려해야 한다고 강력히 건의한다.🔥👊🏻. 현재 제품에 대해 이것은 전환점이 될 수 있다. 그 절차의 가장 중요한 부분을 간소화하여 더 많은 사용자를 시스템에 끌어들이는 것이다😊.

    좋은 웹페이지 즐겨찾기