Pink Spider/AES key Generator

Created Thu, 20 Mar 2025 16:18:45 +0900 Modified Mon, 08 Dec 2025 08:41:47 +0900
622 Words 3 min

Java에서 AES를 사용하기 위해 key, iv 등 생성하는 코드

  • 알고리즘은 AES-128, AES-192, AES-256 어떤 걸 사용하느냐에 따라 key, iv자체의 size가 달라질 수 있습니다
  • 본 글에서는 AES/CBC/PKCS5Padding 256 을 기반으로 했습니다.

Java에서 암복호화에 사용하기 위한 key, iv 는 어떻게 만들까?

  • 현업에서는 key, iv를 데이터 제공 측과 소비측에서 양쪽에서 key, iv를 공유하는데 key, iv를 만드는 방법도 다양했습니다.
  • 본 글에서 다양한 케이스를 코드로 처리한 내용을 적어봅니다.
  • 대체로 key,iv는 base64혹은 hex등으로 encode해서 저장하고, runtime에 decode해서 쓰는 것이 일반적입니다.

key 만들기 다양한 방법

  • base64등 encode 없이 그냥 문자열로 만들기
    public String generateRandomString() {
        String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+";
        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder(32);

        for (int i = 0; i < 32; i++) {
            sb.append(CHARACTERS.charAt(random.nextInt(CHARACTERS.length())));
        }

        return sb.toString();
    }
  • base64는 java.util 을 쓰기도 하고 apache.commons.codec.binary등을 쓸 수 있습니다.
    public void keyGenerator() throws NoSuchAlgorithmException {
        // 1. Secret Key 생성 (AES-256)
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(256); // AES-256 사용
        SecretKey secretKey = keyGenerator.generateKey();

        // 2. IV 생성 (AES CBC 모드에서는 16바이트 IV 필요)
        byte[] iv = new byte[16];
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.nextBytes(iv);

        // 3. Base64로 인코딩하여 출력
        System.out.println("Secret Key (Base64): " + Base64.getEncoder().encodeToString(secretKey.getEncoded()));
        System.out.println("IV (Base64): " + Base64.getEncoder().encodeToString(iv));
    }
  • base64
    public void generateBase64RandomKey() {
        int AES_KEY_SIZE = 32; //256 bit
        int IV_SIZE = 16;

        byte[] secretKeyBytes = new byte[AES_KEY_SIZE];
        byte[] ivBytes = new byte[IV_SIZE];

        new SecureRandom().nextBytes(secretKeyBytes);
        new SecureRandom().nextBytes(ivBytes);

        log.info("secretKeyBytes: {}", Base64.getEncoder().encodeToString(secretKeyBytes));
        log.info("ivBytes: {}", Base64.getEncoder().encodeToString(ivBytes));
    }
  • hex
    public void generateHexRandomKey() {
        int AES_KEY_SIZE = 32; //256 bit
        int IV_SIZE = 16;

        byte[] secretKeyBytes = new byte[AES_KEY_SIZE];
        byte[] ivBytes = new byte[IV_SIZE];

        new SecureRandom().nextBytes(secretKeyBytes);
        new SecureRandom().nextBytes(ivBytes);

        log.info("secretKeyBytes: {}", bytesToHex(secretKeyBytes));
        log.info("ivBytes: {}", bytesToHex(ivBytes));
    }
  • 32byte(256bit) 랜덤 문자열 만들고, base64 encode 하기
    public void generateRandomStringAndGenerateKey() {
        int size = 32;
        String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+";
        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder(size);

        for (int i = 0; i < size; i++) {
            sb.append(CHARACTERS.charAt(random.nextInt(CHARACTERS.length())));
        }

        String secretKeyBase64 = Base64.getEncoder().encodeToString(sb.toString().getBytes());
        String ivBase64 = Base64.getEncoder().encodeToString(sb.substring(0,16).getBytes());
    }
  • 32byte 문자열을 사용해서 base64 encode 하기
    public void generateKeyWithString() {
        String input = "YOUR 32자리 문자열";
        String secretKeyBase64 = Base64.getEncoder().encodeToString(input.getBytes());
        String ivBase64 = Base64.getEncoder().encodeToString(input.substring(0,16).getBytes());
        String decoded = new String(Base64.getDecoder().decode(secretKeyBase64));
    }