Para acessar dados em colunas protegidas por criptografia de coluna em uma aplicação Java, use o driver EncJDBC para conectar-se ao banco de dados. O EncJDBC recupera texto simples de colunas criptografadas com configuração mínima.
Ao fornecer a chave mestra de criptografia, todo o canal de transmissão de dados é criptografado. O cliente EncJDBC descriptografa os dados automaticamente e retorna texto simples que a aplicação pode exibir com alterações mínimas no código.
Pré-requisitos
Execução de uma varredura de sensitive data detection para identificar as colunas que exigem criptografia.
Configuração da criptografia de coluna para o banco de dados de destino e definição da permissão da conta do banco de dados como Ciphertext Permission (JDBC Decryption). Para instruções detalhadas, consulte column encryption.
Detalhes de conexão da instância: nome do host, porta, nome do banco de dados, nome de usuário e senha.
Gerar uma MEK
Faixa de valores: string hexadecimal de 16 bytes, com exatamente 32 caracteres.
Com base no key type selecionado durante a configuração da criptografia de coluna, use uma KMS Key ou gere uma local key como MEK para descriptografar o banco de dados.
KMS key
Garanta a disponibilidade do service KMS ao usar uma chave KMS. Caso contrário, o driver de cliente sempre confidencial EncJDBC não funcionará.
Obtenha o endpoint da instância KMS proprietária da KMS key selecionada na configuração de criptografia de coluna do banco de dados, além do AccessKey ID e do AccessKey secret da conta Alibaba Cloud ou do usuário RAM (que deve ter permissão de descriptografia KMS) para ler essa chave KMS no cliente. Siga estas etapas:
Faça login no console usando uma conta Alibaba Cloud ou um usuário RAM.
-
-
-
Local key
Quando o Encryption Method na configuração de criptografia de coluna do banco de dados estiver definido como Local Key, gere uma MEK. Exemplo: 00112233445566778899aabbccddeeff.
Os métodos comuns de geração incluem geradores de senhas ou funções aleatórias em linguagens de programação.
Exemplos:
No Linux, use a ferramenta OpenSSL integrada executando
openssl rand -hex 16para gerar uma chave.No Windows, instale o pacote de software OpenSSL.
Instruções de integração do cliente
Use JDK 1.8 ou superior para Java.
No lado do cliente, altere o driver de conexão do banco de dados para EncJDBC, atualize a url de conexão do banco de dados e especifique a MEK para acessar texto simples de colunas criptografadas do banco de dados.
1. Instalar dependências
Adicione a seguinte dependência ao arquivo de configuração do projeto Maven pom.xml.
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-cls-jdbc</artifactId>
<version>1.0.10-6</version>
</dependency>
2. Configurar a MEK para conectar ao banco de dados
Os métodos a seguir descrevem como configurar a MEK: configuração de propriedades JDBC, configuração de arquivo e configuração de url. Se houver configuração simultânea de mais de um método, a ordem de prioridade será: configuração de propriedades JDBC > configuração de arquivo > configuração de url.
Na configuração de url, separe múltiplos parâmetros com
&.Em todas as configurações e métodos de conexão abaixo, a
MEKé processada localmente no cliente e enviada com segurança ao servidor usando criptografia de envelope para evitar vazamento daMEK.
Escolha conectar-se ao banco de dados usando uma chave local ou uma chave KMS com base no Encryption method da configuração de criptografia de coluna do banco de dados.
Conectar ao banco de dados usando uma chave KMS
Se usar credenciais temporárias STS para recuperar uma MEK gerenciada pelo KMS, utilize o sdk STS para obter o token de credencial temporária STS. Para exemplos do sdk STS, consulte STS SDK overview.
Não codifique credenciais de acesso (AccessKey ID e AccessKey secret) diretamente no código da aplicação. Este exemplo usa variáveis de ambiente do sistema para gerenciar credenciais de acesso. Para mais detalhes, consulte Configure environment variables on Linux, macOS, and Windows.
Configuração de propriedades JDBC
O JDBC padrão permite definir propriedades personalizadas usando Properties durante a conexão. O exemplo a seguir mostra como configurar as propriedades JDBC e executar o 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 ...
Configuração de url
Incorpore parâmetros para recuperar a chave KMS diretamente na url, conforme mostrado abaixo:
// 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 ...
Conectar ao banco de dados usando uma chave local
Configuração de propriedades JDBC
O JDBC padrão permite definir propriedades personalizadas usando Properties durante a conexão. O exemplo a seguir mostra como configurar as propriedades JDBC e executar o 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 ...
Configuração de arquivo
Importe parâmetros como a MEK necessária por meio de um arquivo de configuração.
A configuração de arquivo aplica-se apenas a MEKs de chave local.
Defina uma property chamada encJdbcConfigFile no projeto e defina seu valor como o caminho do arquivo de configuração (por padrão, o arquivo encjdbc.conf é utilizado). O conteúdo do arquivo de configuração é o seguinte:
MEK=00112233445566778899aabbccddeeff
Coloque o arquivo de configuração em um destes dois locais:
-
Coloque o arquivo no diretório resources do projeto, conforme mostrado abaixo:
src main java resources encjdbc.conf Coloque o arquivo no diretório raiz do projeto (diretório de tempo de execução do programa).
Após configurar o arquivo, nenhuma configuração adicional é necessária no código, conforme mostrado abaixo:
// 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 ...
Configuração de url
Incorpore parâmetros como a MEK diretamente na url, conforme mostrado abaixo:
// 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 dados em texto simples de colunas criptografadas
Após conectar-se com sucesso ao banco de dados, opere-o exatamente como uma consulta JDBC padrão. O EncJDBC descriptografa automaticamente as colunas criptografadas e retorna dados em texto simples.
Código de exemplo:
// 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");
}
Perguntas frequentes
-
P: Por que recebo o erro
Exception in thread "main" java.lang.IllegalAccessError: class com.alibaba.encdb.common.SymCrypto (in unnamed module @0x5c0369c4) cannot access class com.sun.crypto.provider.SunJCE (in module java.base) because module java.base does not export com.sun.crypto.provider to unnamed module @0x5c0369c4ao executar a aplicação?R: Esse erro pode ocorrer porque versões mais recentes do JDK restringem o acesso entre módulos. Para resolver esse problema, adicione a opção de VM
--add-exports=java.base/com.sun.crypto.provider=ALL-UNNAMEDno tempo de execução. Isso exportacom.sun.crypto.providerpara o módulo sem nome e resolve o problema de acesso. -
P: Por que recebo o erro
failed in mek provision: you might have an incorrect mek setting. Detail:gcmEncrypt errorao executar a aplicação?R: Esse problema é comum no Oracle JDK. Use um dos seguintes métodos para resolvê-lo:
Use um Amazon Corretto JDK.
-
Configure manualmente um provedor de segurança para o Oracle JDK seguindo estas etapas:
Localize o diretório de instalação do JDK.
No diretório
<jdk_installation_path>/conf/security/, localize o arquivojava.security.-
Edite o arquivo
java.security. Na seçãoList of providers and their preference orders (see above):, adicione a seguinte linha:security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider