> ## Documentation Index
> Fetch the complete documentation index at: https://developers.argosidentity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cifrado y Descifrado de Datos

> Guía completa para proteger los datos del cliente mediante soluciones de cifrado robustas. Aprenda sobre métodos para minimizar los riesgos de acceso no autorizado y violaciones de datos mientras cumple con los últimos estándares de seguridad.

## Herramienta de Cifrado y Descifrado

<Tip>
  Para fines de desarrollo, proporcione la Herramienta de Cifrado y Descifrado.\
  Puede descargarla mediante este [enlace](https://argos-logo.s3.ap-northeast-2.amazonaws.com/developer_guide/EncryptionTool_0616.zip) y verifique que los resultados sean precisos.

  cf> En macOS, it requires allowing launching this app in the "Privacy & Security" settings menu.
</Tip>

<img src="https://mintlify.s3.us-west-1.amazonaws.com/argosidentity/encryption_preview_image_0611.png" alt="Encrypt Tool Pn" />

## Encryption Options

<CardGroup cols="2">
  <Card title="Types of Encryption Modules" icon="square-1">
    Types of Encryption Modules
  </Card>

  <Card title="Query String Encryption" icon="square-2">
    Query String Encryption
  </Card>

  <Card title="Secure Data Transmission Options" icon="square-3">
    Secure Data Transmission Options
  </Card>

  <Card title="Encryption/Decryption Methods" icon="square-4">
    Encryption/Decryption Methods
  </Card>
</CardGroup>

## 1. Tipos de Módulos de Cifrado

Hay dos tipos de módulos de cifrado disponibles:

* AES-256: Método de cifrado de bloque rápido y simple
* GCM-256: Método de cifrado mejorado con características de autenticación e integridad

### Tipos de Claves de Cifrado

* Clave de API: Clave de API asignada al Proyecto
* Clave de API Personalizada (secretKey): Nueva secretKey emitida desde Liveform para uso

<img src="https://mintlify.s3.us-west-1.amazonaws.com/argosidentity/images/encryption_modules/encryption_en.png" alt="Módulos de cifrado" />

## 2. Cifrado de Cadena de Consulta

Los datos sensibles enviados mediante cadenas de consulta de URL se cifran utilizando el método de cifrado `AES-256-ECB` o `GCM-256`.

<Steps>
  <Step title="Preparar los Datos en Formato JSON">
    <Info>
      Consulte el enlace siguiente para cada descripción de parámetro

      [Parámetros Clave de Cadena de Consulta](https://developers.argosidentity.com/en/idcheck/getting-started/liveform-url/querystring-and-token-guide#2-1-key-query-string-parameters)
    </Info>

    <CodeGroup>
      ```json id_document.json theme={null}
      {
          "email": "email@email.com",
          "userid": "userid",
          "cf1": "value 1",
          "cf2": "value 2",
          "cf3": "value 3",
          "blacklistCountries": false,
          "approvePeriod": false,
          "rejectPeriod": false,
          "ageLimit": false,
          "rejectDuplicateUser": true,
          "token": "token_id",
          "allowedCountries": "USA,KOR"
      }
      ```

      ```json knowledge_based.json theme={null}
      {
          "email": "email@email.com",
          "userid": "userid",
          "cf1": "value 1",
          "cf2": "value 2",
          "cf3": "value 3",
          "knowledgeField": "birthDate,gender,nationality,name,SSN,name,address,phoneNumber",
          "knowledgePrefill" : "gender=male,nationality=USA,SSN=123-34-0001,address=Washington D.C.,name=Brown James,birthDate=1980-01-01,phoneNumber=+15555551234",
          "blacklistCountries": false,
          "ageLimit": false,
          "rejectDuplicateUser": true,
          "allowedCountries": "USA"
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Seleccionar el Módulo de Cifrado AES-256/GCM-256 y la Clave de API o secretKey">
    <img height="200" src="https://mintlify.s3.us-west-1.amazonaws.com/argosidentity/images/encryption_modules/encryption_secretkey_en.png" />

    <nota>
      Una vez emitida, la secretKey no se mostrará nuevamente. Si se pierde, por favor vuelva a emitirla y úsela.
    </nota>
  </Step>

  <Step title="Realizar el Cifrado AES-256/GCM-256 Utilizando la Clave de API Proporcionada">
    <img height="200" src="https://mintcdn.com/argosidentity/vvIXrgN7nH3s-8tI/images/api-reference/api-key.png?fit=max&auto=format&n=vvIXrgN7nH3s-8tI&q=85&s=6868613ab9775ce06ff1d0cf7201e6ab" data-path="images/api-reference/api-key.png" />

    <nota>
      Antes de realizar el cifrado AES-256, por favor verifique los pasos de cifrado y descifrado de la cadena de consulta. <br />
      Si ha recibido una secretKey, por favor utilícela.
    </nota>
  </Step>

  <Step title="Agregar los Datos Cifrados a la URL como el Parámetro de Consulta 'encrypted'">
    <CodeGroup>
      ```text example.url theme={null}
      https://form.argosidentity.com?pid={project_Id}&encrypted={encrypted_json_text}
      ```
    </CodeGroup>
  </Step>
</Steps>

<Warning>
  **Precaución**: Los siguientes parámetros de consulta no están cifrados: `pid`, `lang`, `sid`, `action`.\
  Los parámetros de consulta `pid`, `lang` y los parámetros de consulta `sid`, `action` utilizados en la página de "Proceso Adicional (Inyección)" no admiten cifrado.
</Warning>

## 3. Métodos de Cifrado y Descifrado de Cadena de Consulta

### 3-1. Proceso de Generación de Claves

AES-256

```mermaid theme={null}
 graph LR
    A[API Key] -->|SHA-256 Hash| B[Clave Hasheada]
    B -->|Utilizado en el Cifrado AES-256| C[Cifrado/Descifrado]
```

GCM-256

```mermaid theme={null}
flowchart LR
  %% Generación de Clave
  API[API Key] -->|SHA-256 Hash| KEY[Clave Hasheada de 32 bytes]
  
  %% Cifrado
  KEY --> ENC[AES-256-GCM Cifrado]
  IV[IV Nonce de 12 bytes generación aleatoria] --> ENC
  AAD[AAD Datos Adicionales Autenticados opcional] --> ENC
  DATA[Datos de Texto Plano] --> ENC
  
  ENC --> CT[Texto Cifrado]
  ENC --> TAG[Etiqueta de Autenticación de 16 bytes]
  
  %% Empaquetado
  CT --> OUT[IV + Texto Cifrado + Etiqueta]
  IV --> OUT
  TAG --> OUT
  AAD -->|Encabezado o campo separado| OUT
```

<Steps>
  <Step title="Generar Clave Hasheada">
    <CodeGroup>
      ```javascript Node.js(módulo crypto) theme={null}
      var crypto = require('crypto');
      var hashedKey = crypto.createHash('sha256').update(APIKEY).digest();

      ```

      ```javascript Node.js(biblioteca crypto-js) theme={null}
      const CryptoJS = require('crypto-js');
      const hashedKey = CryptoJS.SHA256(APIKEY);

      ```
    </CodeGroup>
  </Step>

  <Step title="Ejemplo de Cifrado">
    A continuación se presentan ejemplos de cifrado de datos utilizando AES-256

    <CodeGroup>
      ```javascript Node.js(módulo crypto) theme={null}
        var crypto = require('crypto');

        /**
        * @param {string} data - Datos JSON convertidos a cadena
        * @param {string} apiKey - Clave de API del proyecto
        * @returns {string} Datos cifrados
        *
        * para cifrado exacto, use formatJSON.
        * ejemplo abajo,
        * const data = {
            userid: "10912301",
            email: "email@email.com"
        * };
        *
        * no use la forma directa de cadena, como
        * `{"userid":"10912301","email":"email@email.com"}`
        * que no es lo mismo que el cifrado esperado.
        */

        function encrypt(data, apiKey) {
          var hashedKey = crypto.createHash('sha256').update(apiKey).digest();
          var cipher = crypto.createCipheriv('aes-256-ecb', hashedKey, null);
          return cipher.update(data, 'utf8', 'base64') + cipher.final('base64');
        }
      ```

      ```javascript Node.js(biblioteca crypto-js) theme={null}
      const CryptoJS = require('crypto-js');

      const encrypt = (data, apiKey) => {
        const hashedKey = CryptoJS.SHA256(apiKey);
        const encrypted = CryptoJS.AES.encrypt(data, hashedKey, {
          mode: CryptoJS.mode.ECB,
        });
        return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
      };

      ```

      ```java java(biblioteca crypto-js) theme={null}
        import javax.crypto.Cipher;
        import javax.crypto.spec.SecretKeySpec;
        import java.nio.charset.StandardCharsets;
        import java.security.MessageDigest;
        import java.util.Base64;
        
        public class Encryption {
            public static String encrypt(String data, String apiKey) throws Exception {
                // Hashear la clave de API utilizando SHA-256
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
                byte[] hashedKey = digest.digest(apiKey.getBytes(StandardCharsets.UTF_8));
                
                // Asegurarse de que la clave tenga 32 bytes de longitud para compatibilidad con AES-256
                byte[] aesCompatibleKey = new byte[32];
                System.arraycopy(hashedKey, 0, aesCompatibleKey, 0, 32);
                
                // Crear la clave AES para el cifrado
                SecretKeySpec secretKey = new SecretKeySpec(hashedKey, "AES");
                
                // Inicializar el Cipher en modo AES/ECB/PKCS5Padding
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, secretKey);
                
                // Cifrar los datos
                byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
                
                // Devolver el resultado cifrado codificado en Base64
                return Base64.getEncoder().encodeToString(encryptedBytes);
            }
        }
      ```
    </CodeGroup>
  </Step>

  <Step title="Ejemplo de Cifrado GCM">
    A continuación se presentan ejemplos de cifrado de datos utilizando AES-256-GCM

    <CodeGroup>
      ```javascript Node.js(módulo crypto) theme={null}
      var crypto = require('crypto');

      /**
      * @param {string} data - Datos JSON convertidos a cadena
      * @param {string} apiKey - Clave de API del proyecto
      * @returns {string} Datos cifrados en formato hexadecimal (IV + cifrado + etiqueta)
      *
      * El modo GCM proporciona cifrado autenticado e incluye IV y etiqueta de autenticación.
      * El valor de retorno es una cadena hexadecimal codificada del IV de 12 bytes + cifrado + etiqueta de autenticación de 16 bytes.
      */
      function encryptGCM(data, apiKey) {
          var hashedKey = crypto.createHash('sha256').update(apiKey).digest();
          var iv = crypto.randomBytes(12);
          var cipher = crypto.createCipheriv('aes-256-gcm', hashedKey, iv);
          
          var encrypted = cipher.update(data, 'utf8');
          encrypted = Buffer.concat([encrypted, cipher.final()]);
          
          var tag = cipher.getAuthTag();
          var result = Buffer.concat([iv, encrypted, tag]);
          
          return result.toString('hex');
      }

      /**
      * @param {string} encryptedHex - Hexadecimal de datos cifrados
      * @param {string} apiKey - Clave de API del proyecto
      * @returns {string} Datos descifrados
      */
      function decryptGCM(encryptedHex, apiKey) {
          var hashedKey = crypto.createHash('sha256').update(apiKey).digest();
          var encryptedBuffer = Buffer.from(encryptedHex, 'hex');
          
          var iv = encryptedBuffer.slice(0, 12);
          var tag = encryptedBuffer.slice(-16);
          var encrypted = encryptedBuffer.slice(12, -16);
          
          var decipher = crypto.createDecipheriv('aes-256-gcm', hashedKey, iv);
          decipher.setAuthTag(tag);
          
          var decrypted = decipher.update(encrypted);
          decrypted = Buffer.concat([decrypted, decipher.final()]);
          
          return decrypted.toString('utf8');
      }
      ```

      ```javascript Node.js(biblioteca crypto-js) theme={null}
      const CryptoJS = require('crypto-js');

      /**
      * @param {string} data - Datos JSON convertidos a cadena
      * @param {string} apiKey - Clave de API del proyecto
      * @returns {string} Datos cifrados en formato hexadecimal
      */
      const encryptGCM = (data, apiKey) => {
          const hashedKey = CryptoJS.SHA256(apiKey);
          const iv = CryptoJS.lib.WordArray.random(12);
          
          // El modo GCM no está directamente soportado en crypto-js, 
          // así que se recomienda utilizar el módulo crypto de Node.js.
          // A continuación se muestra un ejemplo conceptual.
          
          // Para la implementación real, utilice el módulo crypto de Node.js
          throw new Error('El modo GCM no está soportado en crypto-js. Por favor utilice el módulo crypto de Node.js.');
      };

      /**
      * @param {string} encryptedHex - Hexadecimal de datos cifrados
      * @param {string} apiKey - Clave de API del proyecto
      * @returns {string} Datos descifrados
      */
      const decryptGCM = (encryptedHex, apiKey) => {
          // crypto-js no soporta GCM, así que utilice el módulo crypto de Node.js
          throw new Error('El modo GCM no está soportado en crypto-js. Por favor utilice el módulo crypto de Node.js.');
      };
      ```

      ```java Java theme={null}
      import javax.crypto.Cipher;
      import javax.crypto.spec.GCMParameterSpec;
      import javax.crypto.spec.SecretKeySpec;
      import java.nio.charset.StandardCharsets;
      import java.security.MessageDigest;
      import java.security.SecureRandom;
      import java.util.Base64;
      import java.util.HexFormat;

      public class GCMEncryption {
          private static final int GCM_IV_LENGTH = 12;
          private static final int GCM_TAG_LENGTH = 16;

          /**
          * @param data - Datos JSON convertidos a cadena
          * @param apiKey - Clave de API del proyecto
          * @return Datos cifrados en formato hexadecimal (IV + cifrado + etiqueta)
          */
          public static String encryptGCM(String data, String apiKey) throws Exception {
              // Hashear la clave de API utilizando SHA-256
              MessageDigest digest = MessageDigest.getInstance("SHA-256");
              byte[] hashedKey = digest.digest(apiKey.getBytes(StandardCharsets.UTF_8));
              
              // Crear clave AES para el cifrado
              SecretKeySpec secretKey = new SecretKeySpec(hashedKey, "AES");
              
              // Inicializar Cipher en modo GCM
              Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
              
              // Generar IV de 12 bytes
              byte[] iv = new byte[GCM_IV_LENGTH];
              SecureRandom random = new SecureRandom();
              random.nextBytes(iv);
              
              // Establecer parámetros GCM (longitud de etiqueta 128 bits)
              GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
              cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmSpec);
              
              // Cifrar los datos
              byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
              
              // Combinar IV + cifrado + etiqueta y codificar como hexadecimal
              byte[] result = new byte[iv.length + encryptedBytes.length];
              System.arraycopy(iv, 0, result, 0, iv.length);
              System.arraycopy(encryptedBytes, 0, result, iv.length, encryptedBytes.length);
              
              return HexFormat.of().formatHex(result);
          }

          /**
          * @param encryptedHex - Hexadecimal de datos cifrados
          * @param apiKey - Clave de API del proyecto
          * @return Datos descifrados
          */
          public static String decryptGCM(String encryptedHex, String apiKey) throws Exception {
              // Hashear la clave de API utilizando SHA-256
              MessageDigest digest = MessageDigest.getInstance("SHA-256");
              byte[] hashedKey = digest.digest(apiKey.getBytes(StandardCharsets.UTF_8));
              
              // Crear clave AES para el descifrado
              SecretKeySpec secretKey = new SecretKeySpec(hashedKey, "AES");
              
              // Convertir cadena hexadecimal a array de bytes
              byte[] encryptedData = HexFormat.of().parseHex(encryptedHex);
              
              // Separar IV y cifrado
              byte[] iv = new byte[GCM_IV_LENGTH];
              byte[] ciphertext = new byte[encryptedData.length - GCM_IV_LENGTH];
              System.arraycopy(encryptedData, 0, iv, 0, iv.length);
              System.arraycopy(encryptedData, GCM_IV_LENGTH, ciphertext, 0, ciphertext.length);
              
              // Inicializar Cipher en modo GCM
              Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
              GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
              cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmSpec);
              
              // Descifrar los datos
              byte[] decryptedBytes = cipher.doFinal(ciphertext);
              return new String(decryptedBytes, StandardCharsets.UTF_8);
          }
      }
      ```

      ```python Python theme={null}
      import os
      import base64
      from cryptography.hazmat.primitives import hashes
      from cryptography.hazmat.primitives.ciphers.aead import AESGCM

      def hashed_key(api_key: str) -> bytes:
          """Hashear la clave de API utilizando SHA-256 para generar una clave de 32 bytes"""
          digest = hashes.Hash(hashes.SHA256())
          digest.update(api_key.encode("utf-8"))
          return digest.finalize()

      def encrypt_gcm(data: str, api_key: str) -> str:
          """
          Cifrar datos utilizando el método AES-256-GCM.
          
          Args:
              data: Cadena JSON para cifrar
              api_key: Clave de API del proyecto
              
          Returns:
              formato hexadecimal de datos cifrados (IV + cifrado + etiqueta)
          """
          key = hashed_key(api_key)
          iv = os.urandom(12)  # Generar IV de 12 bytes
          aesgcm = AESGCM(key)
          
          # Cifrar datos (incluye etiqueta de autenticación)
          ct_tag = aesgcm.encrypt(iv, data.encode("utf-8"), None)
          
          # Combinar IV + cifrado + etiqueta y codificar como hexadecimal
          result = iv + ct_tag
          return result.hex()

      def decrypt_gcm(encrypted_hex: str, api_key: str) -> str:
          """
          Descifrar datos cifrados utilizando el método AES-256-GCM.
          
          Args:
              encrypted_hex: formato hexadecimal de datos cifrados
              api_key: Clave de API del proyecto
              
          Returns:
              datos descifrados
          """
          key = hashed_key(api_key)
          encrypted_data = bytes.fromhex(encrypted_hex)
          
          # Separar IV y cifrado+etiqueta
          iv = encrypted_data[:12]
          ct_tag = encrypted_data[12:]
          
          aesgcm = AESGCM(key)
          decrypted_data = aesgcm.decrypt(iv, ct_tag, None)
          return decrypted_data.decode("utf-8")
      ```
    </CodeGroup>
  </Step>

  <Step title="Ejemplo de Descifrado">
    A continuación se presentan ejemplos de descifrado de datos cifrados con AES-256

    <CodeGroup>
      ```javascript Node.js(módulo crypto) theme={null}
          var crypto = require('crypto');

        /**
        * @param {string} encryptedData
        * @param {string} apiKey
        * @returns {string} Datos descifrados
        */
        function decrypt(encryptedData, apiKey) {
          var hashedKey = crypto.createHash('sha256').update(apiKey).digest();
          var decipher = crypto.createDecipheriv('aes-256-ecb', hashedKey, null);
          return decipher.update(encryptedData, 'base64', 'utf8') + decipher.final('utf8');
        }
      ```

      ```javascript Node.js(biblioteca crypto-js) theme={null}
      const CryptoJS = require('crypto-js');

      const decrypt = (encryptedData, apiKey) => {
        const hashedKey = CryptoJS.SHA256(apiKey);
        const decrypted = CryptoJS.AES.decrypt(encryptedData, hashedKey, {
          mode: CryptoJS.mode.ECB
        });
        return decrypted.toString(CryptoJS.enc.Utf8);
      };

      ```
    </CodeGroup>
  </Step>

  <Step title="Ejemplo de Descifrado GCM">
    A continuación se presentan ejemplos de descifrado de datos cifrados con AES-256-GCM

    <CodeGroup>
      ```javascript Node.js(módulo crypto) theme={null}
      var crypto = require('crypto');

      /**
      * @param {string} encryptedHex - Hexadecimal de datos cifrados (IV + cifrado + etiqueta)
      * @param {string} apiKey - Clave de API del proyecto
      * @returns {string} Datos descifrados
      */
      function decryptGCM(encryptedHex, apiKey) {
          var hashedKey = crypto.createHash('sha256').update(apiKey).digest();
          var encryptedBuffer = Buffer.from(encryptedHex, 'hex');
          
          // Separar IV, cifrado y etiqueta
          var iv = encryptedBuffer.slice(0, 12);
          var tag = encryptedBuffer.slice(-16);
          var encrypted = encryptedBuffer.slice(12, -16);
          
          var decipher = crypto.createDecipheriv('aes-256-gcm', hashedKey, iv);
          decipher.setAuthTag(tag);
          
          var decrypted = decipher.update(encrypted);
          decrypted = Buffer.concat([decrypted, decipher.final()]);
          
          return decrypted.toString('utf8');
      }
      ```

      ````javascript Node.js(biblioteca crypto-js) theme={null}
      const CryptoJS = require('crypto-js');

      /**
      * @param {string} encryptedHex - Hexadecimal de datos cifrados
      * @param {string} apiKey - Clave de API del proyecto
      * @returns {string} Datos descifrados
      */
      const decryptGCM = (encryptedHex, apiKey) => {
          // crypto-js no soporta GCM, así que utilice el módulo crypto de Node.js
          throw new Error('El modo GCM no está soportado en crypto-js. Por favor utilice el módulo crypto de Node.js.');
      };

      ```java Java
      import javax.crypto.Cipher;
      import javax.crypto.spec.GCMParameterSpec;
      import javax.crypto.spec.SecretKeySpec;
      import java.nio.charset.StandardCharsets;
      import java.security.MessageDigest;
      import java.util.HexFormat;

      public class GCMDecryption {
          private static final int GCM_IV_LENGTH = 12;
          private static final int GCM_TAG_LENGTH = 16;

          /**
          * @param encryptedHex - Hexadecimal de datos cifrados (IV + cifrado + etiqueta)
          * @param apiKey - Clave de API del proyecto
          * @return Datos descifrados
          */
          public static String decryptGCM(String encryptedHex, String apiKey) throws Exception {
              // Hashear la clave de API utilizando SHA-256
              MessageDigest digest = MessageDigest.getInstance("SHA-256");
              byte[] hashedKey = digest.digest(apiKey.getBytes(StandardCharsets.UTF_8));
              
              // Crear clave AES para el descifrado
              SecretKeySpec key = new SecretKeySpec(hashedKey, "AES");
              
              // Convertir cadena hexadecimal a array de bytes
              byte[] encryptedData = HexFormat.of().parseHex(encryptedHex);
              
              // Separar IV y cifrado+etiqueta
              byte[] iv = new byte[GCM_IV_LENGTH];
              byte[] ciphertext = new byte[encryptedData.length - GCM_IV_LENGTH];
              System.arraycopy(encryptedData, 0, iv, 0, iv.length);
              System.arraycopy(encryptedData, GCM_IV_LENGTH, ciphertext, 0, ciphertext.length);
              
              // Inicializar Cipher en modo GCM
              Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
              GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
              cipher.init(Cipher.DECRYPT_MODE, key, gcmSpec);
              
              // Descifrar los datos
              byte[] decryptedBytes = cipher.doFinal(ciphertext);
              return new String(decryptedBytes, StandardCharsets.UTF_8);
          }
      }
      ````

      ```python Python theme={null}
      import os
      from cryptography.hazmat.primitives import hashes
      from cryptography.hazmat.primitives.ciphers.aead import AESGCM

      def hashed_key(api_key: str) -> bytes:
          """Hashear la clave de API utilizando SHA-256 para generar una clave de 32 bytes"""
          digest = hashes.Hash(hashes.SHA256())
          digest.update(api_key.encode("utf-8"))
          return digest.finalize()

      def decrypt_gcm(encrypted_hex: str, api_key: str) -> str:
          """
          Descifrar datos cifrados utilizando el método AES-256-GCM.
          
          Args:
              encrypted_hex: formato hexadecimal de datos cifrados (IV + cifrado + etiqueta)
              api_key: Clave de API del proyecto
              
          Returns:
              datos descifrados
          """
          key = hashed_key(api_key)
          encrypted_data = bytes.fromhex(encrypted_hex)
          
          # Separar IV y cifrado+etiqueta
          iv = encrypted_data[:12]
          ct_tag = encrypted_data[12:]
          
          aesgcm = AESGCM(key)
          decrypted_data = aesgcm.decrypt(iv, ct_tag, None)
          return decrypted_data.decode("utf-8")
      ```
    </CodeGroup>
  </Step>
</Steps>

## 4. Opciones de Transferencia Segura de Datos

Cifre los datos para una transmisión segura en métodos de API (GET, POST, PATCH) y WEBHOOKs. Los métodos de API utilizan el método de cifrado `AES-256-ECB`, mientras que los WEBHOOKs utilizan `AES-256-CBC`. Asegúrese de que la transferencia segura de datos esté habilitada antes de usarla para proteger información sensible.

Si esta opción está habilitada, el cuerpo de la solicitud debe estar cifrado. Consulte sobre un parámetro del cuerpo que sean datos cifrados. Es necesario cifrar AES-256-ECB y refiérase a las Características Principales y las instrucciones sobre cómo cifrar.

<CodeGroup>
  ```json body theme={null}
  body : encrypt({
  		email : 'string',
  		fullName : 'string',
  		issuingCountry : 'string',
  		birthDate: 'string'
  		...
  	})
  ```
</CodeGroup>

Las respuestas incluyen datos cifrados y la bandera "isEncrypted".

<CodeGroup>
  ```json response.json theme={null}
  body : {
      "data": "encrypted-string",
      "isEncrypted": true
  }
  ```
</CodeGroup>

### 4-1. Características Principales

* Las solicitudes GET, POST, PATCH se cifran utilizando `AES-256-ECB`
* Los datos de WEBHOOK se cifran utilizando `AES-256-CBC`
* Garantiza la integridad de los datos y la autenticación a través de PKI
* Mejora la protección de los datos durante la transmisión

<img height="200" src="https://mintcdn.com/argosidentity/vvIXrgN7nH3s-8tI/images/api-reference/secure-data-transfer.png?fit=max&auto=format&n=vvIXrgN7nH3s-8tI&q=85&s=57e1b28cda5edda003c967e896de0126" data-path="images/api-reference/secure-data-transfer.png" />

### 4-2. Cifrado de Datos de Solicitud de API (AES-256-ECB)

<CodeGroup>
  ```javascript Node.js(biblioteca crypto-js) theme={null}
  const CryptoJS = require('crypto-js');

  function encryptECB(data, apiKey) {
      const hashedKey = CryptoJS.SHA256(apiKey);
      const key = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 8), 32);
      const encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), key, {
          mode: CryptoJS.mode.ECB
      });
      return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
  }
  ```

  ```java AES-256-ECB.java theme={null}
  import javax.crypto.Cipher;
  import javax.crypto.spec.SecretKeySpec;
  import java.nio.charset.StandardCharsets;
  import java.security.MessageDigest;
  import java.util.Base64;
  import com.google.gson.Gson;
  import com.google.gson.JsonObject;

  public class Encryptor {
      public static String encryptECB(JsonObject data, String apiKey) throws Exception {
          Gson gson = new Gson();
          String jsonData = gson.toJson(data);
          
          MessageDigest digest = MessageDigest.getInstance("SHA-256");
          byte[] rawKeyBytes = digest.digest(apiKey.getBytes(StandardCharsets.UTF_8));
          byte[] hashedKey = new byte[32];
          System.arraycopy(rawKeyBytes, 0, hashedKey, 0, 32);
          SecretKeySpec key = new SecretKeySpec(hashedKey, "AES");
          Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
          cipher.init(Cipher.ENCRYPT_MODE, key);
          
          byte[] encryptedBytes = cipher.doFinal(jsonData.getBytes(StandardCharsets.UTF_8));
          return Base64.getEncoder().encodeToString(encryptedBytes);
      }
  }
  ```
</CodeGroup>

### 4-3. Descifrado de Datos de API (AES-256-ECB)

<CodeGroup>
  ````javascript Node.js(biblioteca crypto-js) theme={null}
  const CryptoJS = require('crypto-js');

  function decryptECB(encryptedData, apiKey) {
      const hashedKey = CryptoJS.SHA256(apiKey);
      const key = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 8), 32);
      const cipherParams = CryptoJS.lib.CipherParams.create({
          ciphertext: CryptoJS.enc.Base64.parse(encryptedData)
      });
      const decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
          mode: CryptoJS.mode.ECB
      });
      return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
  }



  ```java AES-256-ECB.java
  import javax.crypto.Cipher;
  import javax.crypto.spec.SecretKeySpec;
  import java.nio.charset.StandardCharsets;
  import java.security.MessageDigest;
  import java.util.Base64;
  import com.google.gson.Gson;
  import com.google.gson.JsonObject;

  public class Encryptor {
      public static JsonObject decryptECB(String encryptedData, String apiKey) throws Exception {
          Gson gson = new Gson();
          MessageDigest digest = MessageDigest.getInstance("SHA-256");
          byte[] hashedKey = digest.digest(apiKey.getBytes(StandardCharsets.UTF_8));
          byte[] aesCompatibleKey = new byte[32];
          System.arraycopy(hashedKey, 0, aesCompatibleKey, 0, 32);
          SecretKeySpec key = new SecretKeySpec(aesCompatibleKey, "AES");
          Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
          cipher.init(Cipher.DECRYPT_MODE, key);
          
          byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
          String jsonData = new String(decryptedBytes, StandardCharsets.UTF_8);
          return gson.fromJson(jsonData, JsonObject.class);
      }
  }
  ````
</CodeGroup>

### 4-4. Cifrado de Datos de WEBHOOK (AES-256-CBC)

<CodeGroup>
  ```javascript Node.js (biblioteca crypto-js) theme={null}
  const CryptoJS = require('crypto-js');

  function generateKeyAndIV(apiKey) {
      const hashedKey = CryptoJS.SHA256(apiKey);
      const key = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 8), 32);
      const iv = CryptoJS.lib.WordArray.create(hashedKey.words.slice(8, 12), 16);
      return { key, iv };
  }

  function encryptCBC(data, apiKey) {
      const { key, iv } = generateKeyAndIV(apiKey);
      const encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), key, { iv: iv, mode: CryptoJS.mode.CBC });
      return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
  }
  ```

  ```java AES-256-CBC.java theme={null}
  import javax.crypto.Cipher;
  import javax.crypto.spec.SecretKeySpec;
  import javax.crypto.spec.IvParameterSpec;
  import java.nio.charset.StandardCharsets;
  import java.security.MessageDigest;
  import java.util.Base64;
  import com.google.gson.Gson;
  import com.google.gson.JsonObject;
  import java.util.Arrays;

  public class Encryptor {
      public static String encryptCBC(JsonObject data, String apiKey) throws Exception {
          String jsonData = new Gson().toJson(data);
          
          MessageDigest digest = MessageDigest.getInstance("SHA-256");
          byte[] hash = digest.digest(apiKey.getBytes(StandardCharsets.UTF_8));
          
          byte[] keyBytes = Arrays.copyOf(hash, 32);
          SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
          
          byte[] ivBytes = new byte[16];
          Arrays.fill(ivBytes, (byte) 0);
          IvParameterSpec iv = new IvParameterSpec(ivBytes);
          
          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
          cipher.init(Cipher.ENCRYPT_MODE, key, iv);
          
          byte[] encryptedBytes = cipher.doFinal(jsonData.getBytes(StandardCharsets.UTF_8));
          return Base64.getEncoder().encodeToString(encryptedBytes);
      }
  }
  ```
</CodeGroup>

### 4-5. Descifrado de Datos de WEBHOOK (AES-256-CBC)

<CodeGroup>
  ```javascript Node.js (biblioteca crypto-js) theme={null}
  const CryptoJS = require('crypto-js');

  function generateKeyAndIV(apiKey) {
      const hashedKey = CryptoJS.SHA256(apiKey);
      const key = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 8), 32);
      const iv = CryptoJS.lib.WordArray.create(hashedKey.words.slice(8, 12), 16);
      return { key, iv };
  }

  function decryptCBC(encryptedData, apiKey) {
      const { key, iv } = generateKeyAndIV(apiKey);
      
      // Crear parámetros de cifrado para descifrado
      const cipherParams = CryptoJS.lib.CipherParams.create({
          ciphertext: CryptoJS.enc.Base64.parse(encryptedData)
      });
      
      // Descifrar los datos
      const decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
          iv: iv,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.Pkcs7
      });
      
      return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
  }
  ```

  ```java AES-256-CBC.java theme={null}
  import javax.crypto.Cipher;
  import javax.crypto.spec.SecretKeySpec;
  import javax.crypto.spec.IvParameterSpec;
  import java.nio.charset.StandardCharsets;
  import java.security.MessageDigest;
  import java.util.Base64;
  import com.google.gson.Gson;
  import com.google.gson.JsonObject;
  import java.util.Arrays;

  public class Encryptor {
      public static JsonObject decryptCBC(String encryptedData, String apiKey) throws Exception {
          MessageDigest digest = MessageDigest.getInstance("SHA-256");
          byte[] hash = digest.digest(apiKey.getBytes(StandardCharsets.UTF_8));
          
          byte[] keyBytes = Arrays.copyOf(hash, 32);
          SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
          
          byte[] ivBytes = new byte[16];
          Arrays.fill(ivBytes, (byte) 0);
          IvParameterSpec iv = new IvParameterSpec(ivBytes);
          
          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
          cipher.init(Cipher.DECRYPT_MODE, key, iv);
          
          byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
          String jsonData = new String(decryptedBytes, StandardCharsets.UTF_8);
          
          return new Gson().fromJson(jsonData, JsonObject.class);
      }
  }
  ```
</CodeGroup>
