logo
Développement
Rechercher
Chiffrement et émission d'AiToken

Chiffrement et émission d'AiToken

Vue d'ensemble

AiToken est le justificatif central de l'intégration à l'espace de travail : il encapsule l'ID de l'organisation et l'e-mail du compte de l'employé, chiffré à l'aide d'une clé publique RSA puis concaténé pour former une URL de connexion dédiée, permettant aux employés d'entreprise d'ouvrir l'espace de travail sans connexion dans l'APP mobile.


Obtenir la clé publique

  1. Ouvrez la version Web → Gestion de l'espaceParamètres avancésMarqueIntégration
  2. Dans la zone d'intégration, repérez la clé publique, cliquez pour l'afficher ou la copier
  3. Si vous devez régénérer la clé (rare, cela invalide tous les Tokens déjà émis), cliquez sur Réinitialiser

Chiffrer un AiToken en tant qu'employé d'entreprise

Aperçu du processus

Étape 1 : e-mail du membre ─── Chiffrement RSA (clé publique) ───► octets emailEncrypted Étape 2 : emailEncrypted ─── Encodage Base64 ───► emailRSAStr Étape 3 : concaténation de la chaîne {projectId}:{emailRSAStr} Étape 4 : chaîne concaténée ─── Encodage Base64 ───► AiToken final
                      
                      Étape 1 : e-mail du membre ─── Chiffrement RSA (clé publique) ───► octets emailEncrypted
Étape 2 : emailEncrypted ─── Encodage Base64 ───► emailRSAStr
Étape 3 : concaténation de la chaîne {projectId}:{emailRSAStr}
Étape 4 : chaîne concaténée ─── Encodage Base64 ───► AiToken final

                    
Ce bloc de code dans la fenêtre flottante

Paramètres de l'algorithme

Paramètre Valeur
Algorithme RSA RSA/ECB/PKCS1Padding (soit RSAES-PKCS1-V1_5)
Format de la clé publique X.509 (SubjectPublicKeyInfo), encodée en Base64
Encodage de sortie Deux passages en Base64

Exemple de code de chiffrement en Java

import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import javax.crypto.Cipher; public class Main { private static final String RSA_ALGORITHM = "RSA"; private static final String RSA_TRANSFORMATION = "RSA/ECB/PKCS1Padding"; /** * Encrypts data using RSA public key. * * @param data The data to encrypt. * @param publicKeyStr The Base64 encoded RSA public key. * @return Encrypted data bytes. */ public static byte[] encrypt(byte[] data, String publicKeyStr) throws Exception { byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(keySpec); Cipher cipher = Cipher.getInstance(RSA_TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * Generates a login key by encrypting the email and combining with projectId. * * @param projectId The project ID. * @param email The user's email. * @param publicKey The Base64 encoded RSA public key. * @return The final login key string. * @throws Exception if encryption fails. */ public static String generateLoginKey(String projectId, String email, String publicKey) throws Exception { byte[] emailEncrypted = encrypt(email.getBytes(StandardCharsets.UTF_8), publicKey); String emailRSAStr = Base64.getEncoder().encodeToString(emailEncrypted); String keyStr = projectId + ":" + emailRSAStr; return Base64.getEncoder().encodeToString(keyStr.getBytes(StandardCharsets.UTF_8)); } public static void main(String[] args) { String projectId = "your project ID"; String email = "your email"; String publicKey = "your public key"; try { String key = generateLoginKey(projectId, email, publicKey); System.out.println(key); } catch (Exception e) { System.err.println("Failed to generate login key: " + e.getMessage()); } } }
                      
                      import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class Main {

    private static final String RSA_ALGORITHM = "RSA";
    private static final String RSA_TRANSFORMATION = "RSA/ECB/PKCS1Padding";

    /**
     * Encrypts data using RSA public key.
     *
     * @param data         The data to encrypt.
     * @param publicKeyStr The Base64 encoded RSA public key.
     * @return Encrypted data bytes.
     */
    public static byte[] encrypt(byte[] data, String publicKeyStr) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);

        Cipher cipher = Cipher.getInstance(RSA_TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * Generates a login key by encrypting the email and combining with projectId.
     *
     * @param projectId The project ID.
     * @param email     The user's email.
     * @param publicKey The Base64 encoded RSA public key.
     * @return The final login key string.
     * @throws Exception if encryption fails.
     */
    public static String generateLoginKey(String projectId, String email, String publicKey) throws Exception {
        byte[] emailEncrypted = encrypt(email.getBytes(StandardCharsets.UTF_8), publicKey);
        String emailRSAStr = Base64.getEncoder().encodeToString(emailEncrypted);
        String keyStr = projectId + ":" + emailRSAStr;
        return Base64.getEncoder().encodeToString(keyStr.getBytes(StandardCharsets.UTF_8));
    }

    public static void main(String[] args) {
        String projectId = "your project ID";
        String email = "your email";
        String publicKey = "your public key";

        try {
            String key = generateLoginKey(projectId, email, publicKey);
            System.out.println(key);
        } catch (Exception e) {
            System.err.println("Failed to generate login key: " + e.getMessage());
        }
    }
}

                    
Ce bloc de code dans la fenêtre flottante

Exemple de code de chiffrement en TypeScript

import * as forge from 'node-forge'; /** * Encrypt data using RSA public key * @param data Data to be encrypted * @param publicKeyStr Base64 encoded public key string * @returns Encrypted byte array */ export function encrypt(data: string, publicKeyStr: string): Uint8Array { try { // Decode Base64 public key const publicKeyBytes = forge.util.decode64(publicKeyStr); // Create public key object const publicKey = forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(publicKeyBytes)); // Use RSA encryption with PKCS1 padding (consistent with Java's default behavior) const encrypted = publicKey.encrypt(data, 'RSAES-PKCS1-V1_5'); // Convert forge's byte string to Uint8Array const bytes = new Uint8Array(encrypted.length); for (let i = 0; i < encrypted.length; i++) { bytes[i] = encrypted.charCodeAt(i) & 0xff; } return bytes; } catch (error) { throw new Error(`RSA encryption failed: ${error}`); } } /** * Convert byte array to Base64 string * @param bytes Byte array * @returns Base64 encoded string */ export function bytesToBase64(bytes: Uint8Array): string { // Convert Uint8Array to string, then use forge's encode64 const binaryString = Array.from(bytes, byte => String.fromCharCode(byte)).join(''); return forge.util.encode64(binaryString); } /** * Convert string to Base64 * @param str String to be encoded * @returns Base64 encoded string */ export function stringToBase64(str: string): string { return forge.util.encode64(str); } /** * Main function - Generate encrypted key string * @param projectId Project ID * @param email Email address * @param publicKey Base64 encoded RSA public key * @returns Final encrypted Base64 string */ export function generateEncryptedKey(projectId: string, email: string, publicKey: string): string { // Use RSA to encrypt email const emailRSAEncrypt = encrypt(email, publicKey); // Convert encryption result to Base64 const emailRSAStr = bytesToBase64(emailRSAEncrypt); // Combine projectId and encrypted email const keyStr = `${projectId}:${emailRSAStr}`; // Encode the entire string with Base64 const result = stringToBase64(keyStr); return result; } // Generate AiToken example // generateEncryptedKey(projectId, email, publicKey)
                      
                      import * as forge from 'node-forge';

/**
 * Encrypt data using RSA public key
 * @param data Data to be encrypted
 * @param publicKeyStr Base64 encoded public key string
 * @returns Encrypted byte array
 */
export function encrypt(data: string, publicKeyStr: string): Uint8Array {
  try {
    // Decode Base64 public key
    const publicKeyBytes = forge.util.decode64(publicKeyStr);

    // Create public key object
    const publicKey = forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(publicKeyBytes));

    // Use RSA encryption with PKCS1 padding (consistent with Java's default behavior)
    const encrypted = publicKey.encrypt(data, 'RSAES-PKCS1-V1_5');

    // Convert forge's byte string to Uint8Array
    const bytes = new Uint8Array(encrypted.length);
    for (let i = 0; i < encrypted.length; i++) {
      bytes[i] = encrypted.charCodeAt(i) & 0xff;
    }
    return bytes;
  } catch (error) {
    throw new Error(`RSA encryption failed: ${error}`);
  }
}

/**
 * Convert byte array to Base64 string
 * @param bytes Byte array
 * @returns Base64 encoded string
 */
export function bytesToBase64(bytes: Uint8Array): string {
  // Convert Uint8Array to string, then use forge's encode64
  const binaryString = Array.from(bytes, byte => String.fromCharCode(byte)).join('');
  return forge.util.encode64(binaryString);
}

/**
 * Convert string to Base64
 * @param str String to be encoded
 * @returns Base64 encoded string
 */
export function stringToBase64(str: string): string {
  return forge.util.encode64(str);
}

/**
 * Main function - Generate encrypted key string
 * @param projectId Project ID
 * @param email Email address
 * @param publicKey Base64 encoded RSA public key
 * @returns Final encrypted Base64 string
 */
export function generateEncryptedKey(projectId: string, email: string, publicKey: string): string {
  // Use RSA to encrypt email
  const emailRSAEncrypt = encrypt(email, publicKey);

  // Convert encryption result to Base64
  const emailRSAStr = bytesToBase64(emailRSAEncrypt);

  // Combine projectId and encrypted email
  const keyStr = `${projectId}:${emailRSAStr}`;

  // Encode the entire string with Base64
  const result = stringToBase64(keyStr);

  return result;
}

// Generate AiToken example
// generateEncryptedKey(projectId, email, publicKey)

                    
Ce bloc de code dans la fenêtre flottante

Générer l'URL de connexion dédiée

Générez l'URL de connexion dédiée du compte de l'employé selon le format {URL d'intégration de l'espace de travail}?{AiToken} :

https://gptbots.ai/space/h5/home?AiToken={AiToken chiffré}&hideClose=true
                      
                      https://gptbots.ai/space/h5/home?AiToken={AiToken chiffré}&hideClose=true

                    
Ce bloc de code dans la fenêtre flottante

Lorsqu'un employé d'entreprise ouvre, dans l'APP mobile, l'URL de connexion chiffrée dédiée à l'e-mail de son compte, il peut ouvrir l'espace de travail correspondant sans connexion.


Consignes de sécurité

Point d'attention Description
Sécurité de la clé publique La clé publique peut être distribuée publiquement, mais le processus d'émission doit être effectué côté serveur, afin d'éviter que le client détienne directement l'ID du projet
Durée de validité du Token L'AiToken n'a pas de notion de durée de validité ; il est recommandé de l'émettre côté backend au moment de la demande et de ne pas le mettre en cache durablement côté APP
Correspondance de l'e-mail L'e-mail contenu dans l'AiToken doit être celui d'un membre déjà existant dans l'espace de travail, sinon l'utilisateur sera signalé comme inexistant
Liaison à l'organisation Un même ID de projet (projectId) correspond à une organisation ; le membre doit appartenir à cette organisation
HTTPS L'URL d'intégration doit être accessible via HTTPS afin d'éviter toute fuite du Token pendant le transport

Documents associés