Java에는 암호화, 복호화를 쉽게 도와주는 Cipher 클래스가 있음
- AES
- Blowfish
- DES
- DESede(DES encrypt-decrypt-encrypt, 3DES, Triple-DES)
- DiffieHellman
- DSA
- OAEP
- PBEWith(digest)And(encryption) ->(digest: MD5, SHA256 등, encryption: DES, AES_128 등)
- PBE
- RC2
- None(없음)
- CBC (Cipher Block Chaining)
- CFB(Cipher Feedback), CFBx(x는 비트 수, ex) CFB8)
- CTR (Counter)
- CTS (Cipher Text Stealing)
- ECB (Electric Codebook)
- OFB (Output Feedback), OFBx
- PCBC (Propagating Cipher Block Chaining)
- NoPadding(패딩 없음)
- *ISO10126Padding
- **OAEPPadding(Optimal Asymmetric Encryption Padding), OAEPWith(digest)And(mgf)Padding
- PKCS1Padding(RSA 알고리즘과 같이 사용)
- PKCS5Padding(패딩 크기 값을 갖는 바이트를 크기 만큼 반복해서 Padding)
- SSL3Padding
*2007년 철회 된 알고리즘, 메시지의 길이가 (7 mod 8) 바이트가 될 때 까지 무작위로 추가하여 추가된 바이트 수를 코딩하는 바이트를 추가하여 (0 mod 8) 바이트로 만들고 블록 암호화 실행
**최적 비대칭 암호화 패딩 방식, digest와 mask 생성 ex) OAEPWithMD5AndMGF1Padding
// Cipher cipher = Cipher.getInstance("알고리즘 종류/모드/패딩"); Cipher cipher1 = Cipher.getInstance("DES/CBC/NoPadding"); Cipher cipher2 = Cipher.getInstance("AES/CBC/NoPadding"); Cipher cipher3 = Cipher.getInstance("AES/ECB/PKCS5Padding"); Cipher cipher4 = Cipher.getInstance("DESede/CBC/NoPadding"); Cipher cipher5 = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); ...
비밀 키 생성하는 클래스
byte[] key = new byte[] { 2, 6, 7, 13, 3, 7, 8, 9 }; // SecretKeySpec secretKeySpec = new SecretKeySpec(byte[] key, "algorithm"); SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
DES CBC 모드나 RSA OAEP 모드같은 IV를 사용하는 *feedback 모드의 암호화에서 초기화 벡터(IV)를 생성
*IV를 사용하는 운용 방식 모드에서 IV값을 초기 값으로 설정하고 연산하는 모든 모드들
byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }; IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher 객체 초기화
작동 모드 설정하는 opmode의 종류
- ENCRYPT_MODE: 암호화 모드로 작동
- DECRYPT_MODE: 복호화 모드로 작동
- WRAP_MODE: Key-Wrapping 모드로 작동
- UNWRAP_MODE: Key-Unwrapping 모드로 작동
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
Cipher 객체 초기화 후 실제 작업(암호화, 복호화)을 수행하기 위해 doFinal()메서드 호출
return cipher.doFinal(plaintextBytes);
import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class CipherTest { public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { final String ENCRYPT_KEY = "KeyIsRequire16,24,32byte"; // 암호화 시 사용될 키 final String ENCRYPT_TARGET = "이 문장을 암호화 할 것입니다."; // 암호화 할 문장 final byte[] IV = ENCRYPT_KEY.substring(0, 16) .getBytes(); // IV 값 설정 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Cipher 객체 인스턴스화 SecretKeySpec secretKeySpec = new SecretKeySpec(ENCRYPT_KEY.getBytes(), "AES"); // 비밀 키 생성 IvParameterSpec iv = new IvParameterSpec(IV); // IV 생성 cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv); // Cipher 초기화 byte[] encryptedBytes = cipher.doFinal(ENCRYPT_TARGET.getBytes()); // 암호화 System.out.println("암호화 된 문자열:" + new String(encryptedBytes, "UTF-8")); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); // 복호화 System.out.println("복호화 된 문자열:" + new String(decryptedBytes, "UTF-8")); } }
- 결과