Oracle 에 SYS
계정으로 접근하여
@$ORACLE_HOME/rdbms/admin/dbmsobtk.sql @$ORACLE_HOME/rdbms/admin/prvtobtk.plb GRANT EXECUTE ON dbms_crypto TO [계정명]; GRANT EXECUTE ON dbms_obfuscation_toolkit TO [계정명]; -- 모든 사용자에게 권한 추가 -- grant execute on dbms_crypto to public; -- grant execute on dbms_obfuscation_toolkit to public;
DBMS_CRYPTO.ENCRYPT
: 암호화 수행. 암호화 데이터 인자로 byte 배열(RAW)를 받음. byte 배열(RAW) 반환.DBMS_CRYPTO.DECRYPT
: 복호화 수행. 복호화 데이터 인자로 hex 문자열 받음. byte 배열(RAW) 반환.DBMS_CRYPTO.*
의 상수들은 PL/SQL 블럭에서만 읽을 수 있다.BEGIN dbms_output.put_line(dbms_crypto.DES_CBC_PKCS5); END; /
dbms_crypto.DES_CBC_PKCS5
→ Java DES/CBC/PKCS5Padding
CBC
모드 등에서 필요하다.byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; IvParameterSpec ivspec = new IvParameterSpec(iv);
-- byte 배열(RAW) 결과 SELECT DBMS_CRYPTO.encrypt(UTL_RAW.CAST_TO_RAW ('Secret Data'), 4353 , UTL_RAW.CAST_TO_RAW ('MYKEY123'),UTL_RAW.CAST_TO_RAW('01234567')) FROM dual; -- VARCHAR2 로 cast 하면 hex 문자열이 나온다. SELECT CAST(DBMS_CRYPTO.encrypt(UTL_RAW.CAST_TO_RAW ('Secret Data'), 4353, UTL_RAW.CAST_TO_RAW ('MYKEY123'),UTL_RAW.CAST_TO_RAW('01234567')) AS VARCHAR2(100)) FROM dual; -- 결과 : 963C9ABD5C20382996DF9E0849F28C45
UTL_RAW.CAST_TO_RAW ('Secret Data')
암호화할 데이터(Secret Data
)를 binary로UTL_I18N.STRING_TO_RAW('암호화할 데이터', 'AL32UTF8')
형태로 UTF-8
byte로.UTL_I18N.RAW_TO_CHAR('RAW 데이터', 'AL32UTF8')
4353
알고리즘 ID : dbms_crypto.DES_CBC_PKCS5
값이다. 이는 사실 여러 알고리즘을 나타내는DBMS_CRYPTO.상수
들의 합이다.UTL_RAW.CAST_TO_RAW ('MYKEY123')
: 비밀번호(Key) binaryUTL_RAW.CAST_TO_RAW('01234567')
Vector. 선택적임.위와 같이 암호화된 데이터를 Java 로 복호화
public void testDecryption() { String CIPHER = "DES/CBC/PKCS5Padding"; byte[] key = DatatypeConverter.parseHexBinary("4D594B4559313233"); // "MYKEY123".getBytes("UTF-8") 와 같다. byte[] value = DatatypeConverter.parseHexBinary("963C9ABD5C20382996DF9E0849F28C45"); // 암호화 결과의 hex String INIT_VECTOR = new String(DatatypeConverter.parseHexBinary("3031323334353637")); SecretKeySpec secretKeySpec=new SecretKeySpec(key, "DES"); IvParameterSpec ivParameterSpec=null; try { ivParameterSpec=new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8")); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } Cipher decryptCipher=null; try { decryptCipher= Cipher.getInstance(CIPHER); decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec,ivParameterSpec); } catch (NoSuchAlgorithmException | NoSuchPaddingException |InvalidKeyException | InvalidAlgorithmParameterException e) { e.printStackTrace(); } String result=""; try { result=new String(decryptCipher.doFinal(value),Charset.forName("UTF-8")); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } System.out.println("Result " + result); // Result Secret Data }
AES256
을 사용하라면 Java JCE(Java Cryptography Extension) 를 설치해야한다. javax.xml.bind.DatatypeConverter#parseHexBinary
를 사용한다.byte bytes[] = {(byte)0, (byte)0, (byte)134, (byte)0, (byte)61}; String hex = javax.xml.bind.DatatypeConverter.printHexBinary(bytes); // 혹은 apache commons codec import org.apache.commons.codec.binary.Hex; ... Hex.encodeHexString(someByteArray));