Para usar o recurso de banco de dados sempre confidencial e criptografar dados em colunas protegidas ao acessar o banco de dados a partir de uma aplicação Java, utilize o driver de cliente EncJDBC. O EncJDBC oferece uma forma prática e econômica de se conectar a um banco de dados sempre confidencial. Este tópico descreve como usar o EncJDBC para acessar um banco de dados sempre confidencial.
Com a chave mestra de criptografia (MEK) configurada, o EncJDBC decifra automaticamente o texto cifrado e retorna texto simples. Esse processo é transparente para a sua aplicação. Basta fazer algumas linhas de configuração para se conectar ao banco de dados sempre confidencial, o que reduz o custo de uso desse recurso.
Prerequisites
Você ativou o recurso de banco de dados sempre confidencial. Para mais informações, consulte Enable the always-confidential database feature.
Você obteve as informações de conexão do banco de dados, como hostname, porta, nome do banco de dados, nome de usuário e senha.
Você configurou uma regra de proteção de dados. Para mais informações, consulte Configure column encryption rules using SQL.
Usage notes
Armazene a chave mestra de criptografia (
MEK) de forma segura.-
Use o JDK 1.8 ou versão superior.
NotaOs exemplos neste tópico usam o Maven
3.9.2e oIntelliJ IDEA Community Edition 2022.3.2.
Procedure
Step 1: Add Maven dependency
Adicione as seguintes dependências ao arquivo pom.xml do seu projeto Maven.
<dependencies>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-encdb-mysql-jdbc</artifactId>
<version>1.0.9-1</version>
</dependency>
</dependencies>
Step 2: Configure the client and query data
Você pode usar o EncJDBC como qualquer outro driver JDBC. No entanto, é necessário configurar primeiro os parâmetros críticos de segurança, incluindo a MEK (chave mestra de criptografia) e o ENC_ALGO (algoritmo de criptografia).
A tabela a seguir descreve os parâmetros e apresenta valores de exemplo.
|
Parâmetro |
Valor de exemplo |
Descrição |
|
MEK |
00112233445566778899aabbccddeeff |
Chave mestra de criptografia que você personaliza e gerencia. Você pode gerar uma MEK usando uma ferramenta de geração de senhas como O valor deve ser uma string hexadecimal de 32 caracteres (16 bytes). Aviso
A MEK é a credencial raiz para acessar dados criptografados. Por motivos de segurança, o banco de dados sempre confidencial não armazena nem gerencia sua MEK e não fornece serviços de geração ou backup para ela. Você é responsável por gerar e fazer backup da sua MEK. Se perder a chave, você perderá permanentemente o acesso aos seus dados. Recomendamos fazer backup da MEK de forma segura. |
|
ENC_ALGO |
SM4_128_CBC |
O algoritmo de criptografia para os dados protegidos. Valores válidos:
Nota
|
Configure MEK and ENC_ALGO
Esta seção descreve três formas de configurar a MEK e o ENC_ALGO. Se você usar mais de um método de configuração, a seguinte ordem de prioridade se aplica: propriedades JDBC > arquivo de configuração > configuração por URL.
Ao usar o método de configuração por URL, concatene vários parâmetros usando o caractere
&.Nos três métodos de conexão, a
MEKé processada localmente no cliente. O cliente usa criptografia de envelope para proteger as chaves de dados enviadas ao servidor. Isso garante que aMEKnunca seja exposta.
JDBC properties
No JDBC padrão, defina atributos personalizados usando um objeto Properties ao se conectar. O exemplo a seguir mostra como configurar as propriedades JDBC para uma conexão:
// Prepare the connection details, such as hostname, port, database name, username, and password.
// ...
String mek=...;
String encAlgo=...;
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);
props.setProperty("ENC_ALGO", encAlgo);
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, props);
// ... Initiate a query ...
Configuration file
Importe parâmetros como a MEK a partir de um arquivo de configuração. No seu projeto, defina uma propriedade chamada encJdbcConfigFile com o caminho do arquivo de configuração. Se você não definir essa propriedade, o driver usará o arquivo padrão encjdbc.conf.
O arquivo de configuração deve conter o seguinte conteúdo:
MEK=
ENC_ALGO=
Coloque o arquivo de configuração em um dos seguintes locais:
Coloque o arquivo
encjdbc.confno diretóriosrc/main/resources/do seu projeto.Coloque o arquivo no diretório raiz do seu projeto, que é o diretório de trabalho em tempo de execução.
Após configurar o arquivo, não é necessária nenhuma configuração adicional no código, conforme mostrado no exemplo a seguir:
// Prepare the connection details, such as hostname, port, database name, username, and password.
// ...
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... Initiate a query ...
URL configuration
Incorpore parâmetros como MEK e ENC_ALGO na URL, conforme mostrado no exemplo a seguir:
// Prepare the connection details, such as hostname, port, database name, username, and password.
// ...
String mek=...;
String encAlgo=...;
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?MEK=%s&ENC_ALGO=%s", hostname, port, dbname, mek, encAlgo);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... Initiate a query ...
Code example
// Replace hostname, port, dbname, username, and password with your instance details.
String hostname = "hostname";
String port = "port";
String dbname = "db";
String username = "user";
String password = "password";
String mek="00112233445566778899aabbccddeeff"; // Example only. Use a more complex key.
String encAlgo="SM4_128_CBC";
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);
props.setProperty("ENC_ALGO", encAlgo);
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s", hostname, port, dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
Connection connection = DriverManager.getConnection(dbUrl, props);
int[] intData = {1, 2, 3, 4, 5, 6};
String[] strData = {"abc", "bcd", "1", "def", "efg", "fgi"};
// Create a table.
connection.createStatement().executeUpdate("drop table if exists test");
connection.createStatement().executeUpdate("create table test (a int, b text)");
// Insert data.
for (int i = 0; i < 6; i++) {
PreparedStatement pstmt = connection.prepareStatement("insert into test values (?,?)");
pstmt.setInt(1, intData[i]);
pstmt.setString(2, strData[i]);
pstmt.executeUpdate();
}
// Check the plaintext data.
ResultSet rs = connection.createStatement().executeQuery("select * from test");
while (rs.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");
}
Saída esperada:
1 abc
2 bcd
3 1
4 def
5 efg
6 fgi
FAQ
-
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-UNNAMEDem 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 JDK Amazon Corretto.
-
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