개발이야기/Java

[Java] AES 암호화, 복호화 예제 및 키 생성 (AES-128)

후린개발자 2023. 12. 11.
반응형

아래 소스코드는 AES 알고리즘을 사용하여 ECB 모드 및 PKCS5Padding 패딩으로 암호화 및 복호화를 구현하였습니다.

 

소스코드

1.키 생성

byte[] key = convertKey("696d697373796f7568616e6765656e61", 16);

 

16진수 문자열을 바이트 배열로 변환하여 AES 키를 생성합니다.

 

 

2.암호화

byte[] enc = encrypt("helloMan", key);
String encryptedResponse = toHexString(enc);

 

주어진 문자열을 AES 알고리즘을 사용하여 생성한 키로 암호화하고, 결과를 16진수 문자열로 변환합니다.

 

 

3.복호화

byte[] tedByte = fromHexToString(encryptedResponse);
String dec = decrypt(tedByte, key);

 

암호화된 16진수 문자열을 다시 바이트 배열로 변환하고, AES를 사용하여 복호화하여 원래 문자열을 얻습니다.

 

 

4.toHexString 메서드

public static String toHexString(byte[] data) {
    return DatatypeConverter.printHexBinary(data).toLowerCase();
}

 

바이트 배열을 16진수 문자열로 변환합니다. DatatypeConverter.printHexBinary 메서드를 사용하여 바이트 배열을 16진수 문자열로 변환하고, 그 결과를 소문자로 변환하여 반환합니다.

 

 

5.convertKey 메서드

public static byte[] convertKey(String key, int radix) throws Exception {}

 

16진수 문자열 키를 바이트 배열로 변환합니다. 진법(radix)을 고려하여 문자열을 파싱 하고, 각 바이트를 생성하여 반환합니다.

 

6.encrypt 메서드

 

평문 문자열을 AES 알고리즘을 사용하여 암호화합니다. Cipher 객체를 초기화하고, 주어진 키를 사용하여 평문을 암호화한 뒤 결과를 반환합니다.

 

 

7.decrypt 메서드

 

암호문 바이트 배열을 AES 알고리즘을 사용하여 복호화합니다. Cipher 객체를 초기화하고, 주어진 키를 사용하여 암호문을 복호화한 뒤 결과를 문자열로 반환합니다.

 

 

8.fromHexToString 메서드

 

16진수 문자열을 바이트 배열로 변환합니다. 16진수 문자열을 바이트 배열로 파싱하고, 그 결과를 반환합니다.

 

 

import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

public class TEST {
    public static void main(String[] args) throws Exception {  
       byte[] key = convertKey("696d697373796f7568616e6765656e61", 16);
       System.out.println("key: "+key);
       
       String str = "helloMan";
       System.out.println("str: "+str);
       
       byte[] enc = encrypt(str, key);
       
       String encryptedResponse = toHexString(enc);
       System.out.println("encryptedResponse: "+encryptedResponse);
       
       byte [] tedByte = fromHexToString(encryptedResponse);
       String dec = decrypt(tedByte, key);
       
       System.out.println("dec: "+dec);
       
    }
    
    /**
     * byte -> hexString
     * @param data
     * @return
     */
    public static String toHexString(byte[] data) {
        return DatatypeConverter.printHexBinary(data).toLowerCase();
    }

    /**
     * 키변환
     * @param key
     * @param radix
     * @return
     * @throws NumberFormatException
     * @throws UnsupportedEncodingException
     */
    public static byte[] convertKey(String key, int radix) throws Exception {
        if (key == null) {
            return null;
        }
        if (radix != 16 && radix != 10 && radix != 8) {
            throw new IllegalArgumentException();
        }
        int divLen = (radix == 16) ? 2 : 3;
        int length = key.length();
        if (length % divLen == 1) {
            throw new IllegalArgumentException("");
        }
        length = length / divLen;
        byte[] bytes = new byte[length];
        for (int i = 0; i < length; i++) {
            int index = i * divLen;
            String a = key.substring(index, index + divLen);
            bytes[i] = (byte) Integer.parseInt(a, radix);
        }
        return bytes;
    }
    
    /**
     * 암호화
     * @param input
     * @param key
     * @return
     */
    public static byte[] encrypt(String plainText, byte[] key/* , String cipherMode */) {
        byte[] encrypted = null;
        String cipherMode = "AES/ECB/PKCS5Padding"; 
        try {
            SecretKeySpec skey = new SecretKeySpec(key, "AES");
            
            //Cipher 객체 인스턴스화(Java에서는 PKCS#5 = PKCS#7이랑 동일)
            Cipher cipher = Cipher.getInstance(cipherMode);
            cipher.init(Cipher.ENCRYPT_MODE, skey);
 
            encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
        } catch (Exception e) {    
            System.out.println(e.toString());
        }
        
        return encrypted;
 
    }
     
    /**
     * 복호화
     * @param input
     * @param key
     * @return
     */
    public static String decrypt(byte[] cipherText, byte[] key/* , String cipherMode */) {
        String plaintext = "";
        String cipherMode = "AES/ECB/PKCS5Padding"; 
        try {
            SecretKeySpec skey = new SecretKeySpec(key, "AES");
            
            //Cipher 객체 인스턴스화(Java에서는 PKCS#5 = PKCS#7이랑 동일)
            Cipher cipher = Cipher.getInstance(cipherMode);
            cipher.init(Cipher.DECRYPT_MODE, skey);
 
            plaintext = new String(cipher.doFinal(cipherText), "UTF-8");
        } catch (Exception e) {    
            System.out.println(e.toString());
        }
        
        return plaintext;
    }
    
    /**
     * hex string to byte
     * @param hexString
     * @return
     */
    public static byte[] fromHexToString(String hexString) {
        byte[] bytes = new byte[hexString.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(hexString.substring(i * 2, i * 2 + 2), 16);
        }
        return bytes;
    }
}

 


 

소스코드 결과

반응형

댓글

💲 추천 글