Entwicklerhandbuch für Chrome Verified Access

Übersicht

Die Chrome Verified Access API ermöglicht Netzwerkdienste wie VPNs, Intranets und so weiter, um kryptografisch zu überprüfen, ob ihre Clients echt sind und den Unternehmensrichtlinien entsprechen. Die meisten großen Unternehmen müssen nur vom Unternehmen verwaltete Geräte in ihren WPA2 EAP-TLS-Netzwerken zulassen, in VPNs und auf Intranet-Seiten mit gegenseitiger TLS-Authentifizierung. Viele bestehende basieren die Lösungen auf heuristischen Prüfungen desselben Kunden, der möglicherweise kompromittiert wurden. Das stellt die Herausforderung dar, den legitimen Status des Geräts bestätigt haben könnte, gefälscht sind. Dieses Handbuch enthält hardwaregestützte kryptografische Garantien des Identität des Geräts sowie, dass sein Status unverändert und richtlinienkonform war. beim Start; den sogenannten bestätigten Zugriff.

Hauptzielgruppe IT-Domainadministratoren für Unternehmen
Technische Komponenten ChromeOS, Google Verified Access API

Voraussetzungen für den bestätigten Zugriff

Schließen Sie die folgenden Schritte ab, bevor Sie den Prozess für den bestätigten Zugriff implementieren.

API aktivieren

Richten Sie ein Google API Console-Projekt ein und aktivieren Sie die API:

  1. Erstellen Sie ein Projekt oder verwenden Sie ein vorhandenes Projekt im Google API Console
  2. Gehen Sie zur Aktivierte APIs und .
  3. Aktivieren Sie die Chrome Verified Access API.
  4. Erstellen Sie einen API-Schlüssel für Ihre Anwendung. Folgen Sie dazu der Google Cloud API-Dokumentation.

Dienstkonto erstellen

Damit der Netzwerkdienst auf die Chrome Verified Access API zugreifen kann, um Ihre Challenge-Reaktion, ein Dienstkonto und einen Dienstkontoschlüssel erstellen (Sie müssen kein neues Cloud-Projekt erstellen, sondern können dasselbe verwenden.)

Nachdem Sie den Dienstkontoschlüssel erstellt haben, sollten Sie ein Dienstkonto haben. Datei mit dem privaten Schlüssel wurde heruntergeladen. Dies ist die einzige Kopie des privaten Schlüssels. Stellen Sie daher sicher, sollten Sie sie an einem sicheren Ort aufbewahren.

Verwaltetes Chromebook registrieren

Sie benötigen ein ordnungsgemäß verwaltetes Chromebook, das für Ihren Chrome-Browser eingerichtet wird .

  1. Das Chromebook muss für die Verwaltung durch Unternehmen oder Bildungseinrichtungen registriert sein.
  2. Der Nutzer des Geräts muss ein registrierter Nutzer in derselben Domain sein.
  3. Die Chrome-Erweiterung für den bestätigten Zugriff muss auf dem Gerät installiert sein.
  4. Richtlinien sind so konfiguriert, dass sie den bestätigten Zugriff aktivieren und Chrome auf die Zulassungsliste setzen Erweiterung und Zugriff auf die API dem Dienstkonto gewähren, das (siehe Dokumentation zur Google Admin-Konsole).

Nutzer und Gerät bestätigen

Entwickler können den bestätigten Zugriff für die Nutzer- oder Gerätebestätigung oder beides verwenden um die Sicherheit zu erhöhen:

  • Gerätebestätigung: Bei erfolgreicher Überprüfung erhalten Sie dass das Chrome-Gerät in einer verwalteten Domain registriert ist und Das Gerät entspricht der Geräterichtlinie für den bestätigten Bootmodus, wie von der Domain angegeben. Administrator. Wenn dem Netzwerkdienst die Berechtigung gewährt wurde, das Gerät zu sehen Identität (siehe Hilfe zur Google Admin-Konsole) bestätigen, wird auch eine Fehlermeldung ausgegeben, Geräte-ID, die für Auditing, Tracking oder zum Aufrufen der Directory API verwendet werden kann.

  • Nutzerbestätigung: Die Nutzerbestätigung ist eine Garantie dafür. Ein angemeldeter Chrome-Nutzer ist ein verwalteter Nutzer, ein registriertes Gerät verwendet und Das Gerät entspricht der Nutzerrichtlinie für den bestätigten Bootmodus, wie von der Domain angegeben. Administrator. Wenn dem Netzwerkdienst eine Berechtigung zum Empfangen zusätzliche Nutzerdaten erhält er auch eine Zertifikatsignierungsanfrage, vom Nutzer (CSR in Form von Signed-public-key-and-challenge, kurz SPKAC, (auch als Keygen-Format bezeichnet).

Nutzer und Gerät bestätigen

  1. Aufgabe anfordern: Die Chrome-Erweiterung auf dem Gerät kontaktiert den bestätigten Absender Greifen Sie auf die API zu, um eine Aufgabe zu erhalten. Die Herausforderung besteht darin, (einem von Google signierten Blob), das für eine Minute gültig ist, Die Identitätsbestätigung (Schritt 3) schlägt fehl, wenn eine veraltete Abfrage verwendet wird.

    Im einfachsten Fall initiiert der Nutzer diesen Vorgang, indem er auf eine Schaltfläche klickt, von der Erweiterung generiert wird (dies entspricht auch der von Google bereitgestellten Beispielerweiterung) funktioniert).

    var apiKey = 'YOUR_API_KEY_HERE';
    var challengeUrlString =
      'https://verifiedaccess.googleapis.com/v2/challenge:generate?key=' + apiKey;
    
    // Request challenge from URL
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open('POST', challengeUrlString, true);
    xmlhttp.send();
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4) {
        var challenge = xmlhttp.responseText;
        console.log('challenge: ' + challenge);
        // v2 of the API returns an encoded challenge so no further challenge processing is needed
      }
    };
    

    Hilfscode zum Codieren der Herausforderung: Bei Verwendung von Version 1 der API -Challenge codiert werden muss.

    // This can be replaced by using a third-party library such as
    // [https://github.com/dcodeIO/ProtoBuf.js/wiki](https://github.com/dcodeIO/ProtoBuf.js/wiki)
    /**
     * encodeChallenge convert JSON challenge into base64 encoded byte array
     * @param {string} challenge JSON encoded challenge protobuf
     * @return {string} base64 encoded challenge protobuf
     */
    var encodeChallenge = function(challenge) {
      var jsonChallenge = JSON.parse(challenge);
      var challengeData = jsonChallenge.challenge.data;
      var challengeSignature = jsonChallenge.challenge.signature;
    
      var protobufBinary = protoEncodeChallenge(
          window.atob(challengeData), window.atob(challengeSignature));
    
      return window.btoa(protobufBinary);
    };
    
    /**
     * protoEncodeChallenge produce binary encoding of the challenge protobuf
     * @param {string} dataBinary binary data field
     * @param {string} signatureBinary binary signature field
     * @return {string} binary encoded challenge protobuf
     */
    var protoEncodeChallenge = function(dataBinary, signatureBinary) {
      var protoEncoded = '';
    
      // See https://developers.google.com/protocol-buffers/docs/encoding
      // for encoding details.
    
      // 0x0A (00001 010, field number 1, wire type 2 [length-delimited])
      protoEncoded += '\u000A';
    
      // encode length of the data
      protoEncoded += varintEncode(dataBinary.length);
      // add data
      protoEncoded += dataBinary;
    
      // 0x12 (00010 010, field number 2, wire type 2 [length-delimited])
      protoEncoded += '\u0012';
      // encode length of the signature
      protoEncoded += varintEncode(signatureBinary.length);
      // add signature
      protoEncoded += signatureBinary;
    
      return protoEncoded;
    };
    
    /**
     * varintEncode produce binary encoding of the integer number
     * @param {number} number integer number
     * @return {string} binary varint-encoded number
     */
    var varintEncode = function(number) {
      // This only works correctly for numbers 0 through 16383 (0x3FFF)
      if (number <= 127) {
        return String.fromCharCode(number);
      } else {
        return String.fromCharCode(128 + (number & 0x7f), number >>> 7);
      }
    };
    
  2. Antwort auf Identitätsbestätigung generieren: Die Chrome-Erweiterung nutzt die Aufgabe, die in Schritt 1 erhalten wurden, um die Chrome API „enterprise.platformKeys“ aufzurufen. Dieses generiert eine signierte und verschlüsselte Antwort zur Identitätsbestätigung, die von der Erweiterung in der Zugriffsanfrage enthält, die er an den Netzwerkdienst sendet.

    In diesem Schritt wird nicht versucht, ein Protokoll zu definieren, Netzwerkdiensts für die Kommunikation nutzen. Beide Entitäten werden von externen Entwicklern erstellt wurden, und es wird nicht vorgegeben, wie sie miteinander kommunizieren. Eine Beispiel: Das Senden einer (URL-codierten) Abfrageantwort als Abfragestring -Parameter, mit HTTP POST oder einem speziellen HTTP-Header.

    Hier ist ein Beispielcode für das Generieren einer Antwort auf die Aufgabe:

    Reaktion auf Herausforderung generieren

      // Generate challenge response
      var encodedChallenge; // obtained by generate challenge API call
      try {
        if (isDeviceVerification) { // isDeviceVerification set by external logic
          chrome.enterprise.platformKeys.challengeKey(
              {
                scope: 'MACHINE',
                challenge: decodestr2ab(encodedChallenge),
              },
              ChallengeCallback);
        } else {
          chrome.enterprise.platformKeys.challengeKey(
              {
                scope: 'USER',
                challenge: decodestr2ab(encodedChallenge),
                registerKey: { 'RSA' }, // can also specify 'ECDSA'
              },
              ChallengeCallback);
        }
      } catch (error) {
        console.log('ERROR: ' + error);
      }
    

    Challenge-Callback-Funktion

      var ChallengeCallback = function(response) {
        if (chrome.runtime.lastError) {
          console.log(chrome.runtime.lastError.message);
        } else {
          var responseAsString = ab2base64str(response);
          console.log('resp: ' + responseAsString);
        ... // send on to network service
       };
      }
    

    Hilfscode für die ArrayBuffer-Konvertierung

      /**
       * ab2base64str convert an ArrayBuffer to base64 string
       * @param {ArrayBuffer} buf ArrayBuffer instance
       * @return {string} base64 encoded string representation
       * of the ArrayBuffer
       */
      var ab2base64str = function(buf) {
        var binary = '';
        var bytes = new Uint8Array(buf);
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
          binary += String.fromCharCode(bytes[i]);
        }
        return window.btoa(binary);
      }
    
      /**
       * decodestr2ab convert a base64 encoded string to ArrayBuffer
       * @param {string} str string instance
       * @return {ArrayBuffer} ArrayBuffer representation of the string
       */
      var decodestr2ab = function(str) {
        var binary_string =  window.atob(str);
        var len = binary_string.length;
        var bytes = new Uint8Array(len);
        for (var i = 0; i < len; i++)        {
            bytes[i] = binary_string.charCodeAt(i);
        }
        return bytes.buffer;
      }
    
  3. Antwort auf Identitätsbestätigung überprüfen: Wenn Sie eine Antwort zur Identitätsbestätigung von einem (etwa als Erweiterung eines bestehenden Authentifizierungsprotokolls), Der Netzwerkdienst sollte die Verified Access API aufrufen, um das Gerät zu überprüfen Identitäts- und Richtlinienstatus (siehe Beispielcode unten). Zur Bekämpfung von Spoofing sollte der Netzwerkdienst den Client identifizieren, mit dem er spricht, und die erwartete Identität des Clients in die Anfrage aufnehmen:

    • Für die Gerätebestätigung muss die erwartete Gerätedomain angegeben werden. . In vielen Fällen handelt es sich dabei wahrscheinlich um einen hartcodierten Wert, da das Netzwerk Ressourcen für eine bestimmte Domain schützt. Falls das nicht bekannt ist im Voraus aus der Nutzeridentität abgeleitet werden.
    • Für die Nutzerbestätigung sollte die E-Mail-Adresse des zu erwartenden Nutzers folgende sein: bereitgestellt. Wir erwarten, dass der Netzwerkdienst seine Nutzer kennt. müssen sich Nutzer anmelden).

    Wenn die Google API aufgerufen wird, führt sie z. B. folgende Prüfungen durch:

    • Vergewissern Sie sich, dass die Antwort zur Identitätsbestätigung von ChromeOS stammt und nicht während der Übertragung geändert
    • Prüfen Sie, ob das Gerät oder der Nutzer vom Unternehmen verwaltet wird.
    • Überprüfen, ob die Identität des Geräts/Nutzers mit den erwarteten Informationen übereinstimmt Identität (falls letztere angegeben ist).
    • Überprüfen Sie, ob die Aufgabe, auf die reagiert wird, Die Adresse darf nicht älter als eine Minute sein.
    • Stellen Sie sicher, dass das Gerät oder der Nutzer der Richtlinie entspricht den Domainadministrator.
    • Prüfen, ob dem Aufrufer (Netzwerkdienst) die Berechtigung zum Aufrufen gewährt wurde die API verwenden.
    • Wenn dem Anrufer die Berechtigung erteilt wurde, zusätzliche Geräte zu erhalten oder Nutzerdaten, einschließlich der Geräte-ID oder der Zertifikatssignatur des Nutzers -Anforderung (CSR) in der Antwort anzugeben.

    In diesem Beispiel wird die gRPC-Bibliothek verwendet.

    import com.google.auth.oauth2.GoogleCredentials;
    import com.google.auth.oauth2.ServiceAccountCredentials;
    import com.google.chrome.verifiedaccess.v2.VerifiedAccessGrpc;
    import com.google.chrome.verifiedaccess.v2.VerifyChallengeResponseRequest;
    import com.google.chrome.verifiedaccess.v2.VerifyChallengeResponseResult;
    import com.google.protobuf.ByteString;
    
    import io.grpc.ClientInterceptor;
    import io.grpc.ClientInterceptors;
    import io.grpc.ManagedChannel;
    import io.grpc.auth.ClientAuthInterceptor;
    import io.grpc.netty.GrpcSslContexts;
    import io.grpc.netty.NettyChannelBuilder;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.util.Arrays;
    import java.util.concurrent.Executors;
    
    // https://cloud.google.com/storage/docs/authentication#generating-a-private-key
    private final String clientSecretFile = "PATH_TO_GENERATED_JSON_SECRET_FILE";
    
    private ManagedChannel channel;
    private VerifiedAccessGrpc.VerifiedAccessBlockingStub client;
    
    void setup() {
    
       channel = NettyChannelBuilder.forAddress("verifiedaccess.googleapis.com", 443)
          .sslContext(GrpcSslContexts.forClient().ciphers(null).build())
          .build();
    
       List<ClientInterceptor> interceptors = Lists.newArrayList();
       // Attach a credential for my service account and scope it for the API.
       GoogleCredentials credentials =
           ServiceAccountCredentials.class.cast(
               GoogleCredentials.fromStream(
                   new FileInputStream(new File(clientSecretFile))));
      credentials = credentials.createScoped(
          Arrays.<String>asList("https://www.googleapis.com/auth/verifiedaccess"));
      interceptors.add(
           new ClientAuthInterceptor(credentials, Executors.newSingleThreadExecutor()));
    
      // Create a stub bound to the channel with the interceptors applied
      client = VerifiedAccessGrpc.newBlockingStub(
          ClientInterceptors.intercept(channel, interceptors));
    }
    
    /**
     * Invokes the synchronous RPC call that verifies the device response.
     * Returns the result protobuf as a string.
     *
     * @param signedData base64 encoded signedData blob (this is a response from device)
     * @param expectedIdentity expected identity (domain name or user email)
     * @return the verification result protobuf as string
     */
    public String verifyChallengeResponse(String signedData, String expectedIdentity)
      throws IOException, io.grpc.StatusRuntimeException {
      VerifyChallengeResponseResult result =
        client.verifyChallengeResponse(newVerificationRequest(signedData,
            expectedIdentity)); // will throw StatusRuntimeException on error.
    
      return result.toString();
    }
    
    private VerifyChallengeResponseRequest newVerificationRequest(
      String signedData, String expectedIdentity) throws IOException {
      return VerifyChallengeResponseRequest.newBuilder()
        .setChallengeResponse(
            ByteString.copyFrom(BaseEncoding.base64().decode(signedData)))
        .setExpectedIdentity(expectedIdentity == null ? "" : expectedIdentity)
        .build();
    }
    
  4. Zugriff gewähren: Dieser Schritt ist auch netzwerkdienstspezifisch. Dies ist ein empfohlene (nicht vorgeschriebene) Implementierung. Mögliche Aktionen sind:

    • Erstellen eines Sitzungscookies
    • Ein Zertifikat für den Nutzer oder das Gerät ausstellen Im Fall der erfolgreichen Nutzung und gehen davon aus, dass dem Netzwerkdienst Zugriff zusätzliche Nutzerdaten hinzufügen (über die Richtlinie in der Admin-Konsole), erhält einen vom Nutzer signierten CSR, mit dem dann der tatsächliche von der Zertifizierungsstelle erhalten haben. Bei der Integration mit MicrosoftR CA hat, kann der Netzwerkdienst als ein Vermittler und nutzen die ICertRequest-Schnittstelle.

Clientzertifikate mit bestätigtem Zugriff verwenden

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> Clientzertifikate mit bestätigtem Zugriff verwenden.

In einem großen Unternehmen kann es mehrere Netzwerkdienste geben, (VPN-Server, WLAN-Zugangspunkte, Firewalls und mehrere Intranet-Websites), die vom bestätigten Zugriff profitieren würden. Wenn Sie jedoch die Logik der Schritte 2–4 (im obigen Abschnitt) in jedem dieser Netzwerkdienste praktisch sein. Oft haben viele dieser Netzwerkdienste bereits die Möglichkeit, Clientzertifikate als Teil ihrer Authentifizierung erforderlich (z. B. EAP-TLS oder gegenseitige TLS-Intranetseiten). Wenn also das Unternehmenszertifikat Zertifizierungsstelle, die diese Clientzertifikate ausstellt, Bedingung für die Ausstellung des Clientzertifikats für die Abfrageantwort festlegen ist, könnte der Besitz des Zertifikats der Nachweis dafür sein, dass die Kundin oder der Kunde authentisch ist und den Unternehmensrichtlinien entspricht. Nach jedem WLAN Zugangspunkt, VPN-Server usw. nach diesem Clientzertifikat suchen anstatt die Schritte 2 bis 4 auszuführen.

Mit anderen Worten: Hier stellt die Zertifizierungsstelle (die das Clientzertifikat an Unternehmen ausstellt) Geräte) übernimmt die Rolle des Netzwerkdienstes in Abbildung 1. Es muss eine die Verified Access API und nur nach der Bestätigung der Identitätsbestätigung übergeben, stellen Sie dem Client das Zertifikat bereit. Die Übergabe des Zertifikats an oder den Client entspricht dem Schritt 4 „Zugriff gewähren“ in Abbildung 1.

Im Folgenden wird beschrieben, wie Sie Clientzertifikate sicher auf Chromebooks abrufen können. in diesem Artikel. Wenn die das in diesem Abschnitt beschriebene Design eingehalten wird. Dann folgt die Erweiterung für den bestätigten Zugriff. und die Onboarding-Erweiterung für Clientzertifikate können in einer Erweiterung kombiniert werden. Weitere Informationen Weitere Informationen zum Schreiben einer Onboarding-Erweiterung für Clientzertifikate