Para acceder a los datos de columnas protegidas con cifrado de columnas desde una aplicación Java, utilice el controlador EncJDBC para conectarse a su base de datos. EncJDBC recupera texto sin formato de las columnas cifradas con una configuración mínima.
Al proporcionar la clave maestra de cifrado, se cifra todo el enlace de transmisión de datos. El cliente EncJDBC descifra automáticamente los datos y devuelve texto sin formato que su aplicación puede mostrar con cambios mínimos en el código.
Requisitos previos
Ha ejecutado un escaneo sensitive data detection para identificar las columnas que requieren cifrado.
Ha configurado el cifrado de columnas para la base de datos de destino y ha establecido el permiso de la cuenta de base de datos en Ciphertext Permission (JDBC Decryption). Para obtener instrucciones detalladas, consulte column encryption.
Detalles de conexión de la instancia: nombre de host, puerto, nombre de la base de datos, nombre de usuario y contraseña.
Generar una MEK
Rango de valores: Una cadena hexadecimal de 16 bytes, con exactamente 32 caracteres de longitud.
Según el key type que seleccionó al configurar el cifrado de columnas, puede usar una KMS Key o generar una local key como su MEK para descifrar la base de datos.
KMS key
Asegúrese de que el servicio KMS esté disponible cuando utilice una clave KMS. De lo contrario, el controlador de cliente siempre confidencial EncJDBC no podrá funcionar.
Obtenga el endpoint de la instancia KMS propietaria de la KMS key seleccionada en la configuración de cifrado de columnas de su base de datos, junto con el AccessKey ID y el AccessKey secret de la cuenta de Alibaba Cloud o del usuario RAM (que debe tener permiso de descifrado de KMS) para leer esta clave KMS desde el cliente. Siga estos pasos:
Inicie sesión en la consola mediante una cuenta de Alibaba Cloud o un usuario RAM.
-
-
-
Local key
Cuando el Encryption Method en la configuración de cifrado de columnas de su base de datos está establecido en Local Key, genere una MEK. Por ejemplo: 00112233445566778899aabbccddeeff.
Los métodos comunes de generación incluyen generadores de contraseñas o funciones aleatorias en lenguajes de programación.
Por ejemplo:
En Linux, utilice la herramienta OpenSSL integrada ejecutando
openssl rand -hex 16para generar una clave.En Windows, instale el paquete de software OpenSSL.
Instrucciones de integración del cliente
Utilice JDK 1.8 o posterior para Java.
En el lado del cliente, cambie el controlador de conexión a la base de datos a EncJDBC, actualice la URL de conexión a la base de datos y especifique la MEK para acceder al texto sin formato de las columnas cifradas de la base de datos.
1. Instalar dependencias
Agregue la siguiente dependencia al archivo de configuración de su proyecto Maven pom.xml.
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-cls-jdbc</artifactId>
<version>1.0.10-3</version>
</dependency>
2. ConfigurarMEK la conexión a la base de datos
Los siguientes métodos describen cómo configurar la MEK: configuración de propiedades JDBC, configuración por archivo y configuración por URL. Si configura más de un método simultáneamente, el orden de prioridad es: configuración de propiedades JDBC > configuración por archivo > configuración por URL.
En la configuración por URL, separe varios parámetros con
&.En todas las configuraciones y métodos de conexión siguientes, la
MEKse procesa localmente en el cliente y se envía de forma segura al servidor mediante cifrado de sobre para evitar la fuga de laMEK.
Elija conectarse a la base de datos mediante una clave local o una clave KMS según el Encryption method en la configuración de cifrado de columnas de su base de datos.
Conexión a la base de datos mediante una clave KMS
Si utiliza credenciales temporales STS para recuperar una MEK gestionada por KMS, use el SDK de STS para obtener el token de credencial temporal STS. Para ejemplos del SDK de STS, consulte STS SDK overview.
No codifique directamente las credenciales de acceso (AccessKey ID y AccessKey secret) en el código de su aplicación. Este ejemplo utiliza variables de entorno del sistema para gestionar las credenciales de acceso. Para más detalles, consulte Configure environment variables on Linux, macOS, and Windows.
Configuración de propiedades JDBC
El estándar JDBC permite establecer propiedades personalizadas mediante Properties durante la conexión. El siguiente ejemplo muestra cómo configurar las propiedades JDBC y ejecutar JDBC:
// Prepare connection information such as hostname, port, database name, username, and password.
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// Retrieve access credentials (AccessKey ID and AccessKey secret) from environment variables.
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// If using STS temporary credentials to read the KMS key, also provide the obtained STS token.
// String stsToken = "yourSecurityToken";
// KMS instance endpoint. Use the public endpoint if public network access is enabled. Use the VPC endpoint for VPC access.
String kmsEndpoint = "kms.cn-hangzhou.aliyuncs.com";
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("ALIBABA_CLOUD_ACCESS_KEY_ID", accessKeyId);
props.setProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET", accessKeySecret);
props.setProperty("ALIBABA_CLOUD_KMS_ENDPOINT", kmsEndpoint);
// props.setProperty("ALIBABA_CLOUD_STS_TOKEN", "stsToken");
// Connection URL format for MySQL: "jdbc:mysql:encdb://%s:%s/%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
// Load the EncJDBC driver for MySQL.
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, props);
// ... Execute queries ...
Configuración por URL
Puede integrar los parámetros para recuperar la clave KMS directamente en la URL, como se muestra a continuación:
// Prepare connection information such as hostname, port, database name, username, and password.
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// Retrieve access credentials (AccessKey ID and AccessKey secret) from environment variables.
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// If using STS temporary credentials to read the KMS key, also provide the obtained STS token.
// String stsToken = "yourSecurityToken";
// KMS instance endpoint. Use the public endpoint if public network access is enabled. Use the VPC endpoint for VPC access.
String kmsEndpoint = "kms.cn-hangzhou.aliyuncs.com";
// Connection URL format for MySQL.
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?ALIBABA_CLOUD_ACCESS_KEY_ID=%s&ALIBABA_CLOUD_ACCESS_KEY_SECRET=%s&ALIBABA_CLOUD_KMS_ENDPOINT=%s", hostname, port, dbname, accessKeyId, accessKeySecret, kmsEndpoint);
// With STS token.
// String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?ALIBABA_CLOUD_ACCESS_KEY_ID=%s&ALIBABA_CLOUD_ACCESS_KEY_SECRET=%s&ALIBABA_CLOUD_KMS_ENDPOINT=%s&ALIBABA_CLOUD_STS_TOKEN=%s", hostname, port, dbname, accessKeyId, accessKeySecret, kmsEndpoint, stsToken);
// Load the EncJDBC driver for MySQL.
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... Execute queries ...
Conexión a la base de datos mediante una clave local
Configuración de propiedades JDBC
El estándar JDBC permite establecer propiedades personalizadas mediante Properties durante la conexión. El siguiente ejemplo muestra cómo configurar las propiedades JDBC y ejecutar JDBC:
// Prepare connection information such as hostname, port, database name, username, and password.
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// Master encryption key.
String mek = "00112233445566778899aabbccddeeff";
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);
// Connection URL format for MySQL: "jdbc:mysql:encdb://%s:%s/%s". For PostgreSQL, use "jdbc:postgresql:encdb://%s:%s/%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
// Load the EncJDBC driver for MySQL. For PostgreSQL, use "com.aliyun.encdb.postgresql.jdbc.EncDriver".
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, props);
// ... Execute queries ...
Configuración por archivo
Puede importar parámetros como la MEK requerida mediante un archivo de configuración.
La configuración por archivo solo aplica para MEK de clave local.
Puede establecer una property llamada encJdbcConfigFile en su proyecto y asignarle como valor la ruta del archivo de configuración (de forma predeterminada, se utiliza el archivo encjdbc.conf). El contenido del archivo de configuración es el siguiente:
MEK=00112233445566778899aabbccddeeff
Puede colocar el archivo de configuración en una de dos ubicaciones:
-
Coloque el archivo en el directorio resources de su proyecto, como se muestra a continuación:
src main java resources encjdbc.conf Coloque el archivo en el directorio raíz del proyecto (el directorio de ejecución del programa).
Después de configurar el archivo, no se necesita configuración adicional en su código, como se muestra a continuación:
// Prepare connection information such as hostname, port, database name, username, and password.
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// Connection URL format for MySQL: "jdbc:mysql:encdb://%s:%s/%s". For PostgreSQL, use "jdbc:postgresql:encdb://%s:%s/%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
// Load the EncJDBC driver for MySQL. For PostgreSQL, use "com.aliyun.encdb.postgresql.jdbc.EncDriver".
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... Execute queries ...
Configuración por URL
Puede integrar parámetros como la MEK directamente en la URL, como se muestra a continuación:
// Prepare connection information such as hostname, port, database name, username, and password.
// ...
String hostname = "your-hostname";
String port = "your-port";
String dbname = "your-database-name";
String username = "your-username";
String password = "your-password";
// Master encryption key.
String mek = "00112233445566778899aabbccddeeff";
// Connection URL format for MySQL: "jdbc:mysql:encdb://%s:%s/%s?MEK=%s". For PostgreSQL, use "jdbc:postgresql:encdb://%s:%s/%s?MEK=%s".
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?MEK=%s", hostname, port, dbname, mek);
// Load the EncJDBC driver for MySQL. For PostgreSQL, use "com.aliyun.encdb.postgresql.jdbc.EncDriver".
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// Get the database connection.
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... Execute queries ...
3. Consultar datos en texto sin formato de columnas cifradas
Después de conectarse correctamente a la base de datos, opérela igual que una consulta JDBC estándar. EncJDBC descifra automáticamente las columnas cifradas y devuelve los datos en texto sin formato.
Código de ejemplo:
// Execute the query.
// Create a query statement.
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM your_table_name");
// Traverse the result set.
while (resultSet.next()) {
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
System.out.print(rs.getString(i + 1));
System.out.print("\t");
}
System.out.print("\n");
}
Solución de problemas
IllegalAccessError: cannot access class com.sun.crypto.provider.SunJCE
Este error ocurre porque las versiones más recientes de JDK restringen el acceso entre módulos de forma predeterminada. Agregue la siguiente opción de VM al ejecutar su programa:
--add-exports=java.base/com.sun.crypto.provider=ALL-UNNAMED
failed in mek provision: gcmEncrypt error
Este es un problema conocido con Oracle JDK. Utilice una de las siguientes soluciones:
Cambiar a Amazon Corretto: una distribución OpenJDK reemplazable que no presenta este problema.
-
Agregar el proveedor de seguridad BouncyCastle a Oracle JDK:
Localice el directorio de instalación de su JDK.
Abra
<jdk-path>/conf/security/java.security.En la sección
List of providers and their preference orders, agregue: ``security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider``