투케이2K

6. (TWOK/UTIL) [Android/Java] C_Encryption - 데이터 암호화 인코딩 (encode) , 디코딩 (decode) , URL 인코딩 및 디코딩 관련 클래스 본문

투케이2K 유틸파일

6. (TWOK/UTIL) [Android/Java] C_Encryption - 데이터 암호화 인코딩 (encode) , 디코딩 (decode) , URL 인코딩 및 디코딩 관련 클래스

투케이2K 2022. 3. 20. 18:48

[설 명]

프로그램 : Android / Java

설 명 : 데이터 암호화 인코딩 (encode) , 디코딩 (decode) , URL 인코딩 및 디코딩 관련 클래스

 

[소스 코드]

package com.example.testapp;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.util.Base64;
import android.util.Log;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class C_Encryption {


    /**
     * TODO [클래스 설명]
     * // -----------------------------------------
     * 1. 데이터 암호화 인코딩, 디코딩 관련 클래스
     * // -----------------------------------------
     * */





    // TODO [Base64 인코딩]
    public static String getBase64EncodeString(String content){

        /**
         * // -----------------------------------------
         * [getBase64EncodeString 메소드 설명]
         * // -----------------------------------------
         * 1. 호출 방법 : C_Encryption.getBase64EncodeString("hello");
         * // -----------------------------------------
         * 2. 리턴 결과 : Base64 암호화 문자열 반환
         * // -----------------------------------------
         * */

        // [Base64 암호화된 문자열로 반환]
        String returnData = String.valueOf(Base64.encodeToString(content.getBytes(), 0));

        // [로그 결과 확인]
        ///*
        Log.i("---","---");
        Log.d("//===========//","================================================");
        Log.i("","\n"+"[C_Encryption >> getBase64EncodeString() :: Base64 인코딩 실시]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[input :: "+String.valueOf(content)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[return :: "+String.valueOf(returnData)+"]");
        Log.d("//===========//","================================================");
        Log.i("---","---");
        // */

        // [리턴 데이터 반환]
        return returnData;
    }





    // TODO [Base64 디코딩]
    public static String getBase64DecodeString(String content){

        /**
         * // -----------------------------------------
         * [getBase64DecodeString 메소드 설명]
         * // -----------------------------------------
         * 1. 호출 방법 : C_Encryption.getBase64DecodeString("aGVsbG8=");
         * // -----------------------------------------
         * 2. 리턴 결과 : Base64 복호화 원본 문자열 반환
         * // -----------------------------------------
         * */

        // [Base64 암호화된 문자열을 >> 복호화된 원본 문자열로 반환]
        String returnData = new String(Base64.decode(content, 0));

        // [로그 결과 확인]
        ///*
        Log.i("---","---");
        Log.d("//===========//","================================================");
        Log.i("","\n"+"[C_Encryption >> getBase64DecodeString() :: Base64 디코딩 실시]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[input :: "+String.valueOf(content)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[return :: "+String.valueOf(returnData)+"]");
        Log.d("//===========//","================================================");
        Log.i("---","---");
        // */

        // [리턴 데이터 반환]
        return returnData;
    }





    // TODO [Aes128 인코딩 : key + iv 사용]
    public static String getAES128EncodeString(String aes128SecretKey, byte[] aes128ivBytes, String data) {

        /**
         * // -----------------------------------------
         * [getAES128EncodeString 메소드 설명]
         * // -----------------------------------------
         * 1. Aes128 암호화 방식을 사용해 데이터 인코딩 수행 실시
         * // -----------------------------------------
         * 2. 호출 방법 : [aes 비밀 키 / aes iv 바이트 [16 바이트 고정] / 인코딩할 데이터]
         *    - C_Encryption.getAES128EncodeString("0123456789abcdef", new byte[16], "hello"); // [byte 공백]
         *    - C_Encryption.getAES128EncodeString("0123456789abcdef", "0123456789abcdef".getBytes(), "hello"); // [byte 지정]
         * // -----------------------------------------
         * 3. 리턴 결과 : aes 암호화 인코딩된 데이터를 base64 데이터로 리턴 실시
         * // -----------------------------------------
         * 4. AES Secret Key 참고 : [aes128 = 16 byte / aes192 = 24 byte / aes256 = 32 byte]
         * // -----------------------------------------
         * */

        // [aes 암호화 인코딩 수행 실시]
        String result = "";
        try {
            byte[] textBytes = data.getBytes("UTF-8");
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(aes128ivBytes); // [알고리즘 스펙]
            SecretKeySpec newKey = new SecretKeySpec(aes128SecretKey.getBytes("UTF-8"), "AES"); // [암호화 알고리즘]
            Cipher cipher = null;
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // [패딩]
            cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec); // [key 지정해 암호화 지정]

            // [리턴 데이터 반환 실시 : base64 데이터로 반환 실시]
            result = Base64.encodeToString(cipher.doFinal(textBytes), Base64.DEFAULT);

            // [로그 출력 실시]
            ///*
            Log.i("---", "---");
            Log.d("//===========//", "================================================");
            Log.i("","\n"+"[C_Encryption >> getAES128EncodeString() :: aes128 비밀키 사용해 인코딩 수행 실시]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[secretKey :: "+String.valueOf(aes128SecretKey)+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[ivBytes :: "+String.valueOf(Arrays.toString(aes128ivBytes))+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[input :: "+String.valueOf(data)+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[return :: "+String.valueOf(result)+"]");
            Log.d("//===========//", "================================================");
            Log.i("---", "---");
            // */
        } catch (Exception e) {
            e.printStackTrace();
        }

        // [리턴 데이터 반환]
        return result;
    }





    // TODO [Aes128 디코딩 : key + iv 사용]
    public static String getAES128DecodeString(String aes128SecretKey, byte[] aes128ivBytes, String data) {

        /**
         * // -----------------------------------------
         * [getAES128DecodeString 메소드 설명]
         * // -----------------------------------------
         * 1. Aes128 암호화 방식을 사용해 데이터 디코딩 수행 실시
         * // -----------------------------------------
         * 2. 호출 방법 : [aes 비밀 키 / aes iv 바이트 [16 바이트 고정] / base64로 된 aes 디코딩 데이터]
         *    - C_Encryption.getAES128DecodeString("0123456789abcdef", new byte[16], "Z0x+8454yr2c7JwSWCOmOQ=="); // [byte 공백]
         *    - C_Encryption.getAES128DecodeString("0123456789abcdef", "0123456789abcdef".getBytes(), "MOfLtxzZ0YgS4+5cPylFYw=="); // [byte 지정]
         * // -----------------------------------------
         * 3. 리턴 결과 : 원본 문자열 데이터 리턴
         * // -----------------------------------------
         * 4. AES Secret Key 참고 : [aes128 = 16 byte / aes192 = 24 byte / aes256 = 32 byte]
         * // -----------------------------------------
         * */

        // [aes 암호화 디코딩 수행 실시]
        String result = "";
        try {
            // [인풋으로 들어온 base64 문자열 데이터를 가지고 디코딩 수행 실시]
            byte[] textBytes = Base64.decode(data, Base64.DEFAULT);
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(aes128ivBytes); // [알고리즘 스펙]
            SecretKeySpec newKey = new SecretKeySpec(aes128SecretKey.getBytes("UTF-8"), "AES"); // [암호화 알고리즘]
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // [패딩]
            cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec); // [key 지정해 암호화 지정]

            // [리턴 데이터 반환 실시 : 원본 문자열 데이터 반환]
            result = new String(cipher.doFinal(textBytes), "UTF-8");

            // [로그 출력 실시]
            Log.i("---", "---");
            Log.d("//===========//", "================================================");
            Log.i("","\n"+"[C_Encryption >> getAES128DecodeString() :: aes128 비밀키 사용해 디코딩 수행 실시]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[secretKey :: "+String.valueOf(aes128SecretKey)+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[ivBytes :: "+String.valueOf(Arrays.toString(aes128ivBytes))+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[input :: "+String.valueOf(data)+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[return :: "+String.valueOf(result)+"]");
            Log.d("//===========//", "================================================");
            Log.i("---", "---");
        } catch (Exception e) {
            e.printStackTrace();
        }

        // [리턴 결과 반환]
        return result;
    }





    // TODO [Aes256 인코딩 : key + iv 사용]
    public static String getAES256EncodeString(String aes256SecretKey, byte[] aes256ivBytes, String data) {

        /**
         * // -----------------------------------------
         * [getAES256EncodeString 메소드 설명]
         * // -----------------------------------------
         * 1. Aes256 암호화 방식을 사용해 데이터 인코딩 수행 실시
         * // -----------------------------------------
         * 2. 호출 방법 : [aes 비밀 키 / aes iv 바이트 [16 바이트 고정] / 인코딩할 데이터]
         *    - C_Encryption.getAES256EncodeString("0123456789abcdef0123456789abcdef", new byte[16], "hello"); // [byte 공백]
         *    - C_Encryption.getAES256EncodeString("0123456789abcdef0123456789abcdef", "0123456789abcdef".getBytes(), "hello"); // [byte 지정]
         * // -----------------------------------------
         * 3. 리턴 결과 : aes 암호화 인코딩된 데이터를 base64 데이터로 리턴 실시
         * // -----------------------------------------
         * 4. AES Secret Key 참고 : [aes128 = 16 byte / aes192 = 24 byte / aes256 = 32 byte]
         * // -----------------------------------------
         * */

        // [aes 암호화 인코딩 수행 실시]
        String result = "";
        try {
            byte[] textBytes = data.getBytes("UTF-8");
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(aes256ivBytes); // [알고리즘 스펙]
            SecretKeySpec newKey = new SecretKeySpec(aes256SecretKey.getBytes("UTF-8"), "AES"); // [암호화 알고리즘]
            Cipher cipher = null;
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // [패딩]
            cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec); // [key 지정해 암호화 지정]

            // [리턴 데이터 반환 실시 : base64 데이터로 반환 실시]
            result = Base64.encodeToString(cipher.doFinal(textBytes), Base64.DEFAULT);

            // [로그 출력 실시]
            ///*
            Log.i("---", "---");
            Log.d("//===========//", "================================================");
            Log.i("","\n"+"[C_Encryption >> getAES256EncodeString() :: aes256 비밀키 사용해 인코딩 수행 실시]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[secretKey :: "+String.valueOf(aes256SecretKey)+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[ivBytes :: "+String.valueOf(Arrays.toString(aes256ivBytes))+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[input :: "+String.valueOf(data)+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[return :: "+String.valueOf(result)+"]");
            Log.d("//===========//", "================================================");
            Log.i("---", "---");
            // */
        } catch (Exception e) {
            e.printStackTrace();
        }

        // [리턴 데이터 반환]
        return result;
    }





    // TODO [Aes256 디코딩 : key + iv 사용]
    public static String getAES256DecodeString(String aes256SecretKey, byte[] aes256ivBytes, String data) {

        /**
         * // -----------------------------------------
         * [getAES256DecodeString 메소드 설명]
         * // -----------------------------------------
         * 1. Aes256 암호화 방식을 사용해 데이터 디코딩 수행 실시
         * // -----------------------------------------
         * 2. 호출 방법 : [aes 비밀 키 / aes iv 바이트 [16 바이트 고정] / base64로 된 aes 디코딩 데이터]
         *    - C_Encryption.getAES256DecodeString("0123456789abcdef0123456789abcdef", new byte[16], "pZwJZBLuy3mDACEQT4YTBw=="); // [byte 공백]
         *    - C_Encryption.getAES256DecodeString("0123456789abcdef0123456789abcdef", "0123456789abcdef".getBytes(), "UQdw44JDqzsxYpkSCwXDIA=="); // [byte 지정]
         * // -----------------------------------------
         * 3. 리턴 결과 : 원본 문자열 데이터 리턴
         * // -----------------------------------------
         * 4. AES Secret Key 참고 : [aes128 = 16 byte / aes192 = 24 byte / aes256 = 32 byte]
         * // -----------------------------------------
         * */

        // [aes 암호화 디코딩 수행 실시]
        String result = "";
        try {
            // [인풋으로 들어온 base64 문자열 데이터를 가지고 디코딩 수행 실시]
            byte[] textBytes = Base64.decode(data, Base64.DEFAULT);
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(aes256ivBytes); // [알고리즘 스펙]
            SecretKeySpec newKey = new SecretKeySpec(aes256SecretKey.getBytes("UTF-8"), "AES"); // [암호화 알고리즘]
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // [패딩]
            cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec); // [key 지정해 암호화 지정]

            // [리턴 데이터 반환 실시 : 원본 문자열 데이터 반환]
            result = new String(cipher.doFinal(textBytes), "UTF-8");

            // [로그 출력 실시]
            ///*
            Log.i("---", "---");
            Log.d("//===========//", "================================================");
            Log.i("","\n"+"[C_Encryption >> getAES256DecodeString() :: aes256 비밀키 사용해 디코딩 수행 실시]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[secretKey :: "+String.valueOf(aes256SecretKey)+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[ivBytes :: "+String.valueOf(Arrays.toString(aes256ivBytes))+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[input :: "+String.valueOf(data)+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[return :: "+String.valueOf(result)+"]");
            Log.d("//===========//", "================================================");
            Log.i("---", "---");
            // */
        } catch (Exception e) {
            e.printStackTrace();
        }

        // [리턴 결과 반환]
        return result;
    }





    // TODO [key hash 키 해시 값 확인 실시]
    public static void getHashKeyData(Context context){

        /**
         * // -----------------------------------------
         * [키 해시 설명]
         * // -----------------------------------------
         * 1. 해시 함수(hash function)는 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑합니다
         * // -----------------------------------------
         * 2. 키 해시는 특정 데이터(data)를 해시 함수(hash function)에 입력한 결과로 받은 리턴값을 말합니다
         * // -----------------------------------------
         * 3. 사용 이유 - 카카오, 구글 등 API 호출 시 hash key를 통해 인증된 사용자인지 여부를 판단합니다
         * // -----------------------------------------
         * 4. 호출 방법 : C_Encryption.getHashKeyData(A_Main.this);
         * // -----------------------------------------
         * */

        try {
            // [로컬 sha1 인증서 HashKey 얻기]
            String sha1_hash = "";
            PackageInfo info_sha1 = context.getPackageManager().getPackageInfo(String.valueOf(context.getPackageName()), PackageManager.GET_SIGNATURES);
            for (Signature signature : info_sha1.signatures) {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(signature.toByteArray());
                sha1_hash = Base64.encodeToString(md.digest(), Base64.DEFAULT);
            }

            // [로컬 sha1 인증서 hex값 얻기]
            String sha1_hex = "";
            byte[] sha1_data_arr = Base64.decode(sha1_hash,0);
            sha1_hex = String.valueOf(getByte_To_HexString(sha1_data_arr));

            // [로컬 sha256 인증서 HashKey 얻기]
            String sha256_hash = "";
            PackageInfo info_sha256 = context.getPackageManager().getPackageInfo(String.valueOf(context.getPackageName()), PackageManager.GET_SIGNATURES);
            for (Signature signature : info_sha256.signatures) {
                MessageDigest md = MessageDigest.getInstance("SHA256");
                md.update(signature.toByteArray());
                sha256_hash = Base64.encodeToString(md.digest(), Base64.DEFAULT);
            }

            // [로컬 sha256 인증서 hex값 얻기]
            String sha256_hex = "";
            byte[] sha256_data_arr = Base64.decode(sha256_hash,0);
            sha256_hex = String.valueOf(getByte_To_HexString(sha256_data_arr));

            // [로컬 md5 인증서 HashKey 얻기]
            String md5_hash = "";
            PackageInfo info_md5 = context.getPackageManager().getPackageInfo(String.valueOf(context.getPackageName()), PackageManager.GET_SIGNATURES);
            for (Signature signature : info_md5.signatures) {
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(signature.toByteArray());
                md5_hash = Base64.encodeToString(md.digest(), Base64.DEFAULT);
            }

            // [로컬 md5 인증서 hex값 얻기]
            String md5_hex = "";
            byte[] md5_data_arr = Base64.decode(md5_hash,0);
            md5_hex = String.valueOf(getByte_To_HexString(md5_data_arr));

            // [구글 플레이 스토어 등록 sha1 인증서 HashKey 얻기]
            byte[] sha1 = { (byte)0x1E, (byte)0xBE, (byte)0x45, (byte)0x66, (byte) 0x7A, (byte) 0x25, (byte) 0x8C, (byte) 0xFC, (byte) 0x9F, (byte) 0x44, (byte) 0xA4, (byte) 0x8F,
                    (byte)0xB7, (byte)0x37, (byte)0xE8, (byte)0x79, (byte)0x88, (byte)0xEC, (byte)0x16, (byte)0x8F, };
            String store_hash = "";
            store_hash = Base64.encodeToString(sha1, Base64.NO_WRAP);

            // [구글 플레이 스토어 등록 sha1 인증서 hex값 얻기]
            String store_hex = "";
            byte[] store_data_arr = Base64.decode(store_hash,0);
            store_hex = String.valueOf(getByte_To_HexString(store_data_arr));

            // [추출한 HashKey 결과 출력 실시]
            ///*
            Log.i("---","---");
            Log.d("//===========//", "================================================");
            Log.i("","\n"+"[C_Encryption >> getHashKeyData() :: HashKey 값 확인 실시]");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[패키지 명 :: "+String.valueOf(context.getPackageName())+"]");
            Log.i("","\n"+"-------------------------------------");
            Log.w("","\n"+"[로컬 sha1 [HashKey] :: "+sha1_hash+"");
            Log.w("","\n"+"[로컬 sha1 [Hex] :: "+sha1_hex+"");
            Log.w("","\n"+"[로컬 sha1 [Hex > HashKey] :: "+getHex_To_HashKeyData(sha1_hex)+"");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[로컬 sha256 [HashKey] :: "+sha256_hash+"");
            Log.i("","\n"+"[로컬 sha256 [Hex] :: "+sha256_hex+"");
            Log.i("","\n"+"[로컬 sha256 [Hex > HashKey] :: "+getHex_To_HashKeyData(sha256_hex)+"");
            Log.i("","\n"+"-------------------------------------");
            Log.i("","\n"+"[로컬 md5 [HashKey] :: "+md5_hash+"");
            Log.i("","\n"+"[로컬 md5 [Hex] :: "+md5_hex+"");
            Log.i("","\n"+"[로컬 md5 [Hex > HashKey] :: "+getHex_To_HashKeyData(md5_hex)+"");
            Log.i("","\n"+"-------------------------------------");
            Log.w("","\n"+"[플레이 스토어 등록 sha1 [HashKey] :: "+store_hash+"");
            Log.w("","\n"+"[플레이 스토어 등록 sha1 [Hex] :: "+store_hex+"");
            Log.w("","\n"+"[플레이 스토어 등록 sha1 [Hex > HashKey] :: "+getHex_To_HashKeyData(store_hex)+"");
            Log.d("//===========//", "================================================");
            Log.i("---","---");
            // */
        }
        catch (PackageManager.NameNotFoundException e) {
            //e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            //e.printStackTrace();
        }
    }
    // [HashKey 값을 바이트 값으로 변환 후 Hex값으로 출력 위함 ]
    public static String getByte_To_HexString(byte buf[]) {
        String Hex_Value = "";
        for(int i=0; i<buf.length; i++) {
            Hex_Value += String.format("%02X", buf[i]);
            if(i < (buf.length-1)){
                Hex_Value += ":";
            }
        }
        return Hex_Value;
    }
    // [인증서 값을 가지고 해시값으로 변환하는 메소드]
    public static String getHex_To_HashKeyData(String data){
        try{
            String parse = "";
            parse = data;
            parse = parse.replaceAll(":","");
            parse = parse.replaceAll("0x", "");
            parse = parse.replaceAll(" ", "");
            byte arr[] = new byte[parse.length()/2];
            int before = 0;
            int after = 2;
            for(int i=0; i<arr.length; i++) {
                String value = parse.substring(before, after);
                arr[i] = new java.math.BigInteger(value, 16).byteValue();
                before += 2;
                after += 2;
            }
            return String.valueOf(Base64.encodeToString(arr, Base64.NO_WRAP));
        }
        catch (Exception e){
            //e.printStackTrace();
        }
        return "";
    }
    
    
    
    
    
    // TODO [URL 인코딩]
    public static String urlEncodeString(String data) {

        /**
         * // -----------------------------------------
         * [urlEncodeString 메소드 설명]
         * // -----------------------------------------
         * 1. URL 인코딩 수행 메소드
         * // -----------------------------------------
         * 2. 호출 방법 : C_Encryption.urlEncodeString("투케이");
         * // -----------------------------------------
         * 3. 리턴 결과 : URL 인코딩 문자열 반환
         * // -----------------------------------------
         * */

        // [초기 리턴 데이터 변수 선언 실시]
        String result = "";

        // [사전 인풋 데이터 널 체크 실시]
        if (data != null
                && data.length()>0
                && data.trim().equals("") == false
                && data.trim().equals("null") == false
                && data.trim().equals("undefined") == false){

            try {
                // [URL 인코딩 수행 실시]
                result = URLEncoder.encode(data, "UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // [로그 출력 실시]
        ///*
        Log.i("---","---");
        Log.d("//===========//","================================================");
        Log.i("","\n"+"[C_Encryption >> urlEncodeString() :: URL 인코딩 수행 실시]");
        Log.i("","\n"+"[input :: "+String.valueOf(data)+"]");
        Log.i("","\n"+"[result :: "+String.valueOf(result)+"]");
        Log.d("//===========//","================================================");
        Log.i("---","---");
        // */

        // [리턴 데이터 반환]
        return result;
    }





    // TODO [URL 디코딩]
    public static String urlDecodeString(String data) {

        /**
         * // -----------------------------------------
         * [urlDecodeString 메소드 설명]
         * // -----------------------------------------
         * 1. URL 디코딩 수행 메소드
         * // -----------------------------------------
         * 2. 호출 방법 : C_Encryption.urlDecodeString("%ED%88%AC%EC%BC%80%EC%9D%B4");
         * // -----------------------------------------
         * 3. 리턴 결과 : 원본 string 문자열 반환
         * // -----------------------------------------
         * */

        // [초기 리턴 데이터 변수 선언 실시]
        String result = "";

        // [사전 인풋 데이터 널 체크 실시]
        if (data != null
                && data.length()>0
                && data.trim().equals("") == false
                && data.trim().equals("null") == false
                && data.trim().equals("undefined") == false){

            try {
                // [URL 디코딩 수행 실시]
                result = URLDecoder.decode(data, "UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // [로그 출력 실시]
        ///*
        Log.i("---","---");
        Log.d("//===========//","================================================");
        Log.i("","\n"+"[C_Encryption >> urlDecodeString() :: URL 디코딩 수행 실시]");
        Log.i("","\n"+"[input :: "+String.valueOf(data)+"]");
        Log.i("","\n"+"[result :: "+String.valueOf(result)+"]");
        Log.d("//===========//","================================================");
        Log.i("---","---");
        // */

        // [리턴 데이터 반환]
        return result;
    }
    
    
    
    
    
    // TODO [Aes256 인코딩 : key + iv + salt 사용]
    public static String getAES_Salt_EncodeString(String aes256SecretKey,
                                                  String aes256IvData,
                                                  String aes256SaltData,
                                                  String data) {

        /**
         * // -----------------------------------------
         * [getAES_Salt_EncodeString 메소드 설명]
         * // -----------------------------------------
         * 1. Aes256 [key + iv + salt] 암호화 방식을 사용해 데이터 인코딩 수행 실시
         * // -----------------------------------------
         * 2. 호출 방법 : [key 데이터 [32 바이트] / iv 데이터 [32 바이트] / salt 데이터 [32 바이트] / 인코딩할 데이터]
         * C_Encryption.getAES_Salt_EncodeString(
         *                 "0123456789abcdef0123456789abcdef", // [secretKey : input : 32 byte]
         *                 "0123456789abcdef0123456789abcdef", // [iv : hex : input : 32 byte]
         *                 "0123456789abcdef0123456789abcdef", // [salt : hex : input : 32 byte]
         *                 "hello" // [input data]
         *         );
         * // -----------------------------------------
         * 3. 리턴 결과 : aes 암호화 인코딩된 데이터를 base64 데이터로 리턴 실시
         * // -----------------------------------------
         * 4. AES Secret Key 참고 : [aes128 = 16 byte / aes192 = 24 byte / aes256 = 32 byte]
         * // -----------------------------------------
         * */

        // [aes 암호화 인코딩 수행 실시]
        String result = "";
        try {
            // [사전 인풋 데이터 체크 실시]
            if (aes256SecretKey != null && aes256SecretKey.length()>0 && !aes256SecretKey.equals("") && !aes256SecretKey.contains("null") && aes256SecretKey.length() == 32
                    && aes256IvData != null && aes256IvData.length()>0 && !aes256IvData.equals("") && !aes256IvData.contains("null") && aes256IvData.length() == 32
                    && aes256SaltData != null && aes256SaltData.length()>0 && !aes256SaltData.equals("") && !aes256SaltData.contains("null") && aes256SaltData.length() == 32
                    && data != null && data.length()>0 && !data.equals("") && !data.contains("null")){

                // [iv 지정 : hex >> byte : 32 글자 헥사 값을 가지고 16 바이트로 변환 실시]
                byte[] iv = HexUtil_To_ByteArray(aes256IvData); // [16 바이트]
                IvParameterSpec ivspec = new IvParameterSpec(iv);


                // [알고리즘 지정]
                SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");


                // [KeySpec : secretKey / salt / iterationCount / keyLength]
                // [salt 지정 : hex >> byte : 32 글자 헥사 값을 가지고 16 바이트로 변환 실시]
                byte[] salt = HexUtil_To_ByteArray(aes256SaltData); // [16 바이트]
                KeySpec spec = new PBEKeySpec(aes256SecretKey.toCharArray(), salt, 1000, 256);
                SecretKey tmp = factory.generateSecret(spec);


                // [SecretKeySpec : 인코딩, 디코딩 수행에서 AES 지정]
                SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES"); // [인코딩, 디코딩 수행에서 AES 지정]


                // [Cipher : 암호화 타입 및 패딩 지정]
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // [인코딩, 디코딩 수행에서 필요한 패딩 지정]
                cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec); // [KeySpec + iv]


                // [리턴 데이터 삽입 실시]
                result = Base64.encodeToString(cipher.doFinal(data.getBytes()), 0); // [base64 결과 반환 데이터]
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // [로그 출력 실시]
        ///*
        Log.i("---", "---");
        Log.d("//===========//", "================================================");
        Log.i("","\n"+"[C_Encryption >> getAES_Salt_EncodeString() :: aes256 [key + iv + salt] 사용해 인코딩 수행 실시]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[secretKey :: "+String.valueOf(aes256SecretKey)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[iv [hex] :: "+String.valueOf(aes256IvData)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[salt [hex] :: "+String.valueOf(aes256SaltData)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[input data :: "+String.valueOf(data)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[return :: "+String.valueOf(result)+"]");
        Log.d("//===========//", "================================================");
        Log.i("---", "---");
        // */

        // [리턴 데이터 반환]
        return result;
    }





    // TODO [Aes256 디코딩 : key + iv + salt 사용]
    public static String getAES_Salt_DecodeString(String aes256SecretKey,
                                                  String aes256IvData,
                                                  String aes256SaltData,
                                                  String data) {

        /**
         * // -----------------------------------------
         * [getAES_Salt_DecodeString 메소드 설명]
         * // -----------------------------------------
         * 1. Aes256 [key + iv + salt] 암호화 방식을 사용해 데이터 디코딩 수행 실시
         * // -----------------------------------------
         * 2. 호출 방법 : [key 데이터 [32 바이트] / iv 데이터 [32 바이트] / salt 데이터 [32 바이트] / 디코딩할 데이터]
         * C_Encryption.getAES_Salt_DecodeString(
         *                 "0123456789abcdef0123456789abcdef", // [secretKey : input : 32 byte]
         *                 "0123456789abcdef0123456789abcdef", // [iv : hex : input : 32 byte]
         *                 "0123456789abcdef0123456789abcdef", // [salt : hex : input : 32 byte]
         *                 "0yHy16m2dy5OpZH2+NX/4w==" // [input data]
         *         );
         * // -----------------------------------------
         * 3. 리턴 결과 : 원본 문자열 데이터 리턴
         * // -----------------------------------------
         * 4. AES Secret Key 참고 : [aes128 = 16 byte / aes192 = 24 byte / aes256 = 32 byte]
         * // -----------------------------------------
         * */

        // [aes 암호화 디코딩 수행 실시]
        String result = "";
        try {
            // [사전 인풋 데이터 체크 실시]
            if (aes256SecretKey != null && aes256SecretKey.length()>0 && !aes256SecretKey.equals("") && !aes256SecretKey.contains("null") && aes256SecretKey.length() == 32
                    && aes256IvData != null && aes256IvData.length()>0 && !aes256IvData.equals("") && !aes256IvData.contains("null") && aes256IvData.length() == 32
                    && aes256SaltData != null && aes256SaltData.length()>0 && !aes256SaltData.equals("") && !aes256SaltData.contains("null") && aes256SaltData.length() == 32
                    && data != null && data.length()>0 && !data.equals("") && !data.contains("null")){

                // [iv 지정 : hex >> byte : 32 글자 헥사 값을 가지고 16 바이트로 변환 실시]
                byte[] iv = HexUtil_To_ByteArray(aes256IvData); // [16 바이트]
                IvParameterSpec ivspec = new IvParameterSpec(iv);


                // [알고리즘 지정]
                SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");


                // [KeySpec : secretKey / salt / iterationCount / keyLength]
                // [salt 지정 : hex >> byte : 32 글자 헥사 값을 가지고 16 바이트로 변환 실시]
                byte[] salt = HexUtil_To_ByteArray(aes256SaltData); // [16 바이트]
                KeySpec spec = new PBEKeySpec(aes256SecretKey.toCharArray(), salt, 1000, 256);
                SecretKey tmp = factory.generateSecret(spec);


                // [SecretKeySpec : 인코딩, 디코딩 수행에서 AES 지정]
                SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES"); // [인코딩, 디코딩 수행에서 AES 지정]


                // [Cipher : 암호화 타입 및 패딩 지정]
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // [인코딩, 디코딩 수행에서 필요한 패딩 지정]
                cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec); // [KeySpec + iv]


                // [리턴 데이터 삽입 실시]
                result = new String(cipher.doFinal(Base64.decode(data, 0))); // [원본 데이터 반환]
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // [로그 출력 실시]
        ///*
        Log.i("---", "---");
        Log.d("//===========//", "================================================");
        Log.i("","\n"+"[C_Encryption >> getAES_Salt_DecodeString() :: aes256 [key + iv + salt] 사용해 디코딩 수행 실시]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[secretKey :: "+String.valueOf(aes256SecretKey)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[iv [hex] :: "+String.valueOf(aes256IvData)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[salt [hex] :: "+String.valueOf(aes256SaltData)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[input data :: "+String.valueOf(data)+"]");
        Log.i("","\n"+"-------------------------------------");
        Log.i("","\n"+"[return :: "+String.valueOf(result)+"]");
        Log.d("//===========//", "================================================");
        Log.i("---", "---");
        // */

        // [리턴 결과 반환]
        return result;
    }





    // TODO [Hex String to Byte array 변환 실시]
    public static byte[] HexUtil_To_ByteArray(String data) {
        byte[] temp = new byte[data.length() / 2];
        for(int i = 0; i < data.length() / 2; ++i) {
            temp[i] = toByte(data.substring(i * 2, i * 2 + 2));
        }
        return temp;
    }
    public static byte toByte(String hexStr) {
        byte result = 0;
        String hex = hexStr.toUpperCase();
        for(int i = 0; i < hex.length(); ++i) {
            char c = hex.charAt(hex.length() - i - 1);
            byte b = toByte(c);
            result = (byte)(result | (b & 15) << i * 4);
        }
        return result;
    }
    private static byte toByte(char c) {
        switch(c) {
            case '0':
                return 0;
            case '1':
                return 1;
            case '2':
                return 2;
            case '3':
                return 3;
            case '4':
                return 4;
            case '5':
                return 5;
            case '6':
                return 6;
            case '7':
                return 7;
            case '8':
                return 8;
            case '9':
                return 9;
            case ':':
            case ';':
            case '<':
            case '=':
            case '>':
            case '?':
            case '@':
            default:
                return 0;
            case 'A':
                return 10;
            case 'B':
                return 11;
            case 'C':
                return 12;
            case 'D':
                return 13;
            case 'E':
                return 14;
            case 'F':
                return 15;
        }
    }


} // TODO [클래스 종료]

 

[결과 출력]


반응형
Comments