Java Cipher

P·2021년 12월 8일
0

Cipher

Java에는 암호화, 복호화를 쉽게 도와주는 Cipher 클래스가 있음

  • javax.crypto.Cipher에 포함
  • Object 클래스를 상속받는 Cipher 클래스
  • Cipher 객체를 생성하기 위해서는 getInstance() 메서드를 호출
  • getInstance()의 인자로 "알고리즘" 또는 "알고리즘/모드/패딩" 형식으로 암호화 방식 지정 가능

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

Cipher에서 지원하는 알고리즘 모드의 종류

  • 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)

Cipher에서 지원하는 알고리즘 패딩의 종류

  • 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


Java Cipher 객체 인스턴스화

// 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");
...

SecretKeySpec

비밀 키 생성하는 클래스

  • Javax.crypto.spec.SecretKeySpec에 포함
  • KeySpec, SecretKey 인터페이스를 구현한 클래스
  • 생성자를 통해 비밀 키를 생성할 수 있음
  • 생성자에 입력되는 파라미터들로 byte[] key, String algorithm 을 입력

Java SecretKeySpec 객체 생성

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");

IvParameterSpec

DES CBC 모드나 RSA OAEP 모드같은 IV를 사용하는 *feedback 모드의 암호화에서 초기화 벡터(IV)를 생성

  • Javax.crypto.spec.IvParameterSpec에 포함
  • AlgorithmParameterSpec 인터페이스를 구현한 클래스
  • 생성자를 통해 IV를 생성할 수 있음
  • 생성자에 입력되는 파라미터로 byte[] iv를 입력

*IV를 사용하는 운용 방식 모드에서 IV값을 초기 값으로 설정하고 연산하는 모든 모드들

Java IvParameterSpec 객체 생성

byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivSpec = new IvParameterSpec(iv);

Cipher.init

Cipher 객체 초기화

  • Cipher의 작동 모드를 설정하는 opmode 설정
  • 인증서(certificate), 키(Key), 초기 벡터(IV) 등을 파라미터로 입력

작동 모드 설정하는 opmode의 종류

  • ENCRYPT_MODE: 암호화 모드로 작동
  • DECRYPT_MODE: 복호화 모드로 작동
  • WRAP_MODE: Key-Wrapping 모드로 작동
  • UNWRAP_MODE: Key-Unwrapping 모드로 작동

Java Cipher 객체 초기화

cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);

Cipher.doFinal

Cipher 객체 초기화 후 실제 작업(암호화, 복호화)을 수행하기 위해 doFinal()메서드 호출

  • 입력한 byte[] 배열 평문을 암호화, 복호화 된 byte[] 배열로 반환

Java Cipher.doFinal 사용

return cipher.doFinal(plaintextBytes);

Cipher 문자열 암호화 예시


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"));
    }
}
  • 결과
profile
개인 정리 공간

0개의 댓글