테스트를 진행할 때 h2 데이터베이스를 사용
일부 SQL 함수 H2 데이터베이스에서는 지원하지 않음
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Function "AES_DECRYPT" not found; SQL statement:
MySQL 모드로 설정되어 있지만 여전히 사용 불가
jdbc:h2:~/test;MODE=MySQL
지원되지 않는 함수를 java로 사용자 정의 함수로 구현
CREATE ALIAS IF NOT EXISTS LAST_INSERT_ID_MAX AS '
@CODE
int lastInsertIdMax(int id) throws Exception {
return id;
}
';
CREATE ALIAS IF NOT EXISTS DATE_FORMAT AS '
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
@CODE
String dateFormat(Timestamp ts, String pattern) throws Exception {
if (ts == null || pattern == null || pattern.isEmpty()) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(ts);
}
';
CREATE ALIAS IF NOT EXISTS AES_ENCRYPT AS '
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
@CODE
byte[] aesEncrypt(String plainText, String key) throws Exception {
// MySQL에서는 암호화 할 때 어떤 길이의 key가 들어와도 내부에서 정규화 후 실행
// java 에서는 16, 24, 32 길이의 key만 허용
// key 길이 정규화 코드
byte[] finalKey = new byte[16];
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
for (int i = 0; i < keyBytes.length; i++) {
finalKey[i % 16] ^= keyBytes[i];
}
if (plainText == null){
plainText="";
}
SecretKeySpec secretKey = new SecretKeySpec(finalKey, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
}
';
CREATE ALIAS IF NOT EXISTS AES_DECRYPT AS '
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
@CODE
String aesDecrypt(byte[] encrypted, String key) throws Exception {
byte[] finalKey = new byte[16];
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
for (int i = 0; i < keyBytes.length; i++) {
finalKey[i % 16] ^= keyBytes[i];
}
SecretKeySpec secretKey = new SecretKeySpec(finalKey, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted, StandardCharsets.UTF_8);
}
';
CREATE ALIAS IF NOT EXISTS HEX AS '
@CODE
String hex(byte[] data) {
StringBuilder sb = new StringBuilder();
for (byte b : data) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
';
CREATE ALIAS IF NOT EXISTS UNHEX AS '
@CODE
byte[] unhex(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
int hi = Character.digit(hex.charAt(i), 16);
int lo = Character.digit(hex.charAt(i + 1), 16);
data[i / 2] = (byte)((hi << 4) + lo);
}
return data;
}
';