4단계로 SSMS에서 열암호화를 진행한다.

암호화할 열 선택 > 암호화 유형: 결정적 (Deterministic) > 암호화 키: CEK_Auto1 (새 열) 또는 자동 생성된 이름 > 다음 클릭

Azure에 로그인하려 했으나 조직메일이 아닌 개인메일로 가입해서 안되는것 같다.


⚠️ SSMS의 Always Encrypted 마법사는 "조직 계정"(회사/학교) 필요
⚠️ Gmail 같은 개인 Microsoft 계정은 지원 안 됨
✅ 해결책: Java 애플리케이션에서 서비스 주체로 설정
다시 Azure Portal로 이동해서 Key Vault 에서 키를 생성한다.

+ 생성/가져오기를 클릭하고 아래와 같이 진행한다.

그 다음 생성된 키 클릭해서 키 식별자 URL 복사한다.

자바로 CEK/CMK 키 생성을 구현한다.
package com.example.encrypt;
import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerConnection;
import java.security.SecureRandom;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
/**
* Always Encrypted - CMK/CEK 생성 스크립트
* Azure Key Vault를 사용하여 Column Master Key와 Column Encryption Key를 생성합니다.
*/
public class AlwaysEncryptedSetup {
// Azure AD 앱 설정
private static final String CLIENT_ID = "your-client-id";
private static final String CLIENT_SECRET = "your-client-secret";
private static final String TENANT_ID = "your-tenant-id";
// Azure Key Vault 설정
private static final String KEY_VAULT_URL = "https://your-keyvault.vault.azure.net/";
private static final String KEY_NAME = "CMK-Name"; // Key Vault에 생성한 키 이름
// SQL Server 설정
private static final String DB_URL = "jdbc:sqlserver://your-server:1433;databaseName=YourDB;encrypt=true;trustServerCertificate=true";
private static final String DB_USER = "sa";
private static final String DB_PASSWORD = "password";
// CMK/CEK 이름 (SQL Server에 등록될 이름)
private static final String CMK_NAME = "CMK_AzureKeyVault";
private static final String CEK_NAME = "CEK_AzureKeyVault";
public static void main(String[] args) {
try {
System.out.println("=== Always Encrypted 설정 시작 ===\n");
// 1. Azure Key Vault Provider 등록
System.out.println("[1/3] Azure Key Vault Provider 등록...");
registerProvider();
System.out.println(" 완료\n");
// 2. Column Master Key 생성
System.out.println("[2/3] Column Master Key 생성...");
createCMK();
System.out.println(" 완료\n");
// 3. Column Encryption Key 생성
System.out.println("[3/3] Column Encryption Key 생성...");
createCEK();
System.out.println(" 완료\n");
System.out.println("=== CMK/CEK 생성 완료! ===");
} catch (Exception e) {
System.err.println("오류: " + e.getMessage());
e.printStackTrace();
}
}
/**
* Azure Key Vault Provider 등록
*/
private static void registerProvider() throws Exception {
ClientSecretCredential credential = new ClientSecretCredentialBuilder()
.clientId(CLIENT_ID)
.clientSecret(CLIENT_SECRET)
.tenantId(TENANT_ID)
.build();
SQLServerColumnEncryptionAzureKeyVaultProvider provider =
new SQLServerColumnEncryptionAzureKeyVaultProvider(credential);
Map<String, SQLServerColumnEncryptionKeyStoreProvider> providers = new HashMap<>();
providers.put("AZURE_KEY_VAULT", provider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(providers);
}
/**
* Column Master Key 생성
* - Key Vault의 키를 참조하는 CMK를 SQL Server에 등록
*/
private static void createCMK() throws SQLException {
String keyPath = KEY_VAULT_URL + "keys/" + KEY_NAME;
String sql = "CREATE COLUMN MASTER KEY [" + CMK_NAME + "] " +
"WITH (KEY_STORE_PROVIDER_NAME = 'AZURE_KEY_VAULT', " +
"KEY_PATH = '" + keyPath + "')";
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
Statement stmt = conn.createStatement()) {
stmt.execute(sql);
System.out.println(" CMK: " + CMK_NAME);
System.out.println(" Key Path: " + keyPath);
}
}
/**
* Column Encryption Key 생성
* - CEK를 생성하고 CMK(Azure Key Vault)로 암호화하여 SQL Server에 등록
*/
private static void createCEK() throws Exception {
// 32바이트(256비트) 랜덤 CEK 생성
byte[] cekPlaintext = new byte[32];
new SecureRandom().nextBytes(cekPlaintext);
// Azure Key Vault Provider로 CEK 암호화
ClientSecretCredential credential = new ClientSecretCredentialBuilder()
.clientId(CLIENT_ID)
.clientSecret(CLIENT_SECRET)
.tenantId(TENANT_ID)
.build();
SQLServerColumnEncryptionAzureKeyVaultProvider provider =
new SQLServerColumnEncryptionAzureKeyVaultProvider(credential);
String keyPath = KEY_VAULT_URL + "keys/" + KEY_NAME;
byte[] encryptedCek = provider.encryptColumnEncryptionKey(keyPath, "RSA_OAEP", cekPlaintext);
// SQL Server에 CEK 등록
String sql = "CREATE COLUMN ENCRYPTION KEY [" + CEK_NAME + "] " +
"WITH VALUES (COLUMN_MASTER_KEY = [" + CMK_NAME + "], " +
"ALGORITHM = 'RSA_OAEP', " +
"ENCRYPTED_VALUE = 0x" + bytesToHex(encryptedCek) + ")";
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
Statement stmt = conn.createStatement()) {
stmt.execute(sql);
System.out.println(" CEK: " + CEK_NAME);
}
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
}
사용한 Maven은 아래와 같다.
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.8.1.jre8</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.11.1</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-keys</artifactId>
<version>4.7.1</version>
</dependency>
CMK/CEK 생성 완료되면 다시 열암호화를 진행한다.

다음을 눌러서 암호화를 진행한다.

아래와 같이 나오면 열암호화가 완료된다.

'개발 > Azure' 카테고리의 다른 글
| [AZURE] DB 암호화3 Key Vault 권한 설정 (0) | 2025.12.17 |
|---|---|
| [AZURE] DB 암호화2 Azure AD 앱 등록 (0) | 2025.12.15 |
| [AZURE] DB 암호화1 Azure Key Vault 정리/생성 (0) | 2025.12.11 |