Criptografía de Always Encrypted

Se aplica a:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

En este documento se describen los algoritmos y mecanismos de cifrado para derivar el material criptográfico usado en la característica Always Encrypted de SQL Server y Azure SQL Database.

Claves, almacenes de claves y algoritmos de cifrado de claves

Always Encrypted utiliza claves de dos tipos: claves maestras de columna y claves de cifrado de columna.

Una clave maestra de columna (CMK) es una clave de cifrado de claves (por ejemplo, una clave que se usa para cifrar otras claves). Asimismo, se encuentra siempre bajo el control del cliente y se almacena en un almacén de claves externo. Un controlador de cliente habilitado para Always Encrypted interactúa con el almacén de claves a través de un proveedor de almacén CMK, que puede formar parte de la biblioteca de controladores (un proveedor de Microsoft/sistema) o de la aplicación cliente (un proveedor personalizado). Actualmente, las bibliotecas de controladores de cliente incluyen proveedores de almacén de claves de Microsoft para el almacén de certificados de Windows y módulos de seguridad de hardware (HSM). Para ver la lista actual de proveedores, consulte CREATE COLUMN MASTER KEY (Transact-SQL). Un desarrollador de aplicaciones puede proporcionar un proveedor personalizado para un almacén arbitrario.

Una clave de cifrado de columna (CEK) es una clave de cifrado de contenido (por ejemplo, una clave que se utiliza para proteger los datos) que está protegida por una CMK.

Todos los proveedores de almacenes CMK de Microsoft cifran los CEK mediante RSA con relleno de cifrado asimétrico óptimo (RSA-OAEP). El proveedor de almacén de claves compatible con Microsoft Cryptography API: Next Generation (CNG) en .NET Framework (clase SqlColumnEncryptionCngProvider) usa los parámetros predeterminados especificados por RFC 8017 en la sección A.2.1. Estos parámetros predeterminados utilizan una función hash de SHA-1 y una función de generación de máscara de MGF1 con SHA-1. Todos los demás proveedores de almacenes de claves usan SHA-256.

Always Encrypted usa internamente módulos criptográficos validados por FIPS 140-2.

Algoritmo de cifrado de datos

Always Encrypted usa el algoritmo AEAD_AES_256_CBC_HMAC_SHA_256 para cifrar los datos de la base de datos.

AEAD_AES_256_CBC_HMAC_SHA_256 se deriva del borrador de especificación en https://tools.ietf.org/html/draft-mcgrew-aead-aes-cbc-hmac-sha2-05. Utiliza un esquema de cifrado autenticado con asociados datos, con un enfoque conocido como "cifrar y, después, generar la MAC". Es decir, el texto no cifrado se cifra primero y se genera la MAC según el texto cifrado resultante.

Para ocultar los patrones, AEAD_AES_256_CBC_HMAC_SHA_256 usa el modo de funcionamiento Cipher Block Chaining (CBC), con el que se transmite un valor inicial al sistema conocido como el "vector de inicialización" (IV). Encontrará una descripción completa del modo CBC en https://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf.

AEAD_AES_256_CBC_HMAC_SHA_256 calcula un valor de texto cifrado para un valor de texto no cifrado determinado siguiendo estos pasos.

Paso 1: generación del vector de inicialización (IV)

Always Encrypted admite dos variantes de AEAD_AES_256_CBC_HMAC_SHA_256:

  • Aleatorio

  • Determinista

Para el cifrado aleatorio, el IV se genera aleatoriamente. Como consecuencia, cada vez que se cifre el mismo texto no cifrado, se genera un texto cifrado distinto, lo que evita que se divulgue cualquier información.

When using randomized encryption: IV = Generate cryptographicaly random 128bits  

En el caso del cifrado determinista, el IV no se genera de forma aleatoria, sino que se genera a partir del valor de texto no cifrado mediante el siguiente algoritmo:

When using deterministic encryption: IV = HMAC-SHA-256( iv_key, cell_data ) truncated to 128 bits.  

Donde iv_key se deriva de la CEK del siguiente modo:

iv_key = HMAC-SHA-256(CEK, "Microsoft SQL Server cell IV key" + algorithm + CEK_length)  

Se realiza el truncamiento del valor HMAC para ajustar un bloque de datos según se necesite para el IV. Como resultado, el cifrado determinista siempre genera el mismo texto cifrado para un valor de texto no cifrado concreto, lo que permite deducir si dos valores de texto no cifrado son iguales al comparar sus correspondientes valores de texto cifrado. Esta divulgación de información limitada permite al sistema de base de datos admitir la comparación de igualdad en valores de columna cifrados.

El cifrado determinista resulta más eficaz para ocultar los patrones, en comparación con las alternativas (como el uso de un valor de IV predefinido).

Paso 2: cálculo del texto cifrado AES_256_CBC

Tras calcular el IV, se genera el texto cifrado AES_256_CBC :

aes_256_cbc_ciphertext = AES-CBC-256(enc_key, IV, cell_data) with PKCS7 padding.  

Donde la clave de cifrado (enc_key) se deriva la CEK del siguiente modo:

enc_key = HMAC-SHA-256(CEK, "Microsoft SQL Server cell encryption key" + algorithm + CEK_length )  

Paso 3: cálculo de la MAC

Posteriormente, la dirección MAC se calcula mediante el siguiente algoritmo:

MAC = HMAC-SHA-256(mac_key, versionbyte + IV + Ciphertext + versionbyte_length)  

Donde:

versionbyte = 0x01 and versionbyte_length = 1
mac_key = HMAC-SHA-256(CEK, "Microsoft SQL Server cell MAC key" + algorithm + CEK_length)  

Paso 4: concatenación

Por último, el valor cifrado se genera mediante la concatenación del byte de la versión del algoritmo, la dirección MAC, el IV y el texto de cifrado AES_256_CBC:

aead_aes_256_cbc_hmac_sha_256 = versionbyte + MAC + IV + aes_256_cbc_ciphertext  

Longitud del texto cifrado

Las longitudes (en bytes) de los componentes concretos del texto cifrado AEAD_AES_256_CBC_HMAC_SHA_256 son las siguientes:

  • versionbyte: 1.

  • MAC: 32.

  • IV: 16.

  • aes_256_cbc_ciphertext: (FLOOR (DATALENGTH(cell_data)/ block_size) + 1)* block_size, donde:

    • block_size es de 16 bytes.

    • cell_data es un valor de texto sin formato.

    Por lo tanto, el tamaño mínimo de aes_256_cbc_ciphertext es de un bloque, lo que equivale a 16 bytes.

Por lo tanto, es posible calcular la longitud de un texto cifrado, que sea el resultado de cifrar valores de texto no cifrado determinados (cell_data), mediante la siguiente fórmula:

1 + 32 + 16 + (FLOOR(DATALENGTH(cell_data)/16) + 1) * 16  

Por ejemplo:

  • Un valor de texto no cifrado int de tipo Long de 4 bytes se convierte en un valor binario Long de 65 bytes tras el cifrado.

  • Un valor de texto no cifrado nchar(1000) de tipo Long de 2000 bytes se convierte en un valor binario Long de 2065 bytes tras el cifrado.

La siguiente tabla contiene una lista completa de tipos de datos y la longitud del texto cifrado para cada uno de ellos.

Tipo de datos Longitud del texto cifrado [bytes]
bigint 65
binary Varía. Utilice la fórmula anterior.
bit 65
char Varía. Utilice la fórmula anterior.
date 65
datetime 65
datetime2 65
datetimeoffset 65
decimal 81
float 65
geography N/D (no compatible).
geometry N/D (no compatible).
hierarchyid N/D (no compatible).
image N/D (no compatible).
int 65
money 65
nchar Varía. Utilice la fórmula anterior.
ntext N/D (no compatible).
numeric 81
nvarchar Varía. Utilice la fórmula anterior.
real 65
smalldatetime 65
smallint 65
smallmoney 65
sql_variant N/D (no compatible).
sysname N/D (no compatible).
texto N/D (no compatible).
time 65
timestamp

(rowversion)
N/D (no compatible).
tinyint 65
uniqueidentifier 81
varbinary Varía. Utilice la fórmula anterior.
varchar Varía. Utilice la fórmula anterior.
xml N/D (no compatible).

Referencia de .NET

Para obtener más información sobre los algoritmos que se han visto en este documento, consulte los archivos SqlAeadAes256CbcHmac256Algorithm.cs, SqlColumnEncryptionCertificateStoreProvider.cs y SqlColumnEncryptionCertificateStoreProvider.cs en la referencia de .NET.

Consulte también