Notice
Recent Posts
Recent Comments
Link
투케이2K
278. (AndroidStudio/android/java) [재등록] aes 암호화 파생 인코딩 , 디코딩 수행 실시 - secretkey , iv , salt 본문
Android
278. (AndroidStudio/android/java) [재등록] aes 암호화 파생 인코딩 , 디코딩 수행 실시 - secretkey , iv , salt
투케이2K 2022. 3. 14. 08:03[개발 환경 설정]
개발 툴 : AndroidStudio
개발 언어 : java
[소스 코드]
package com.test.app;
import android.util.Base64;
import android.util.Log;
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_AES256 {
/**
* TODO [클래스 설명]
* // -----------------------------------------
* 1. AES256 암호화 수행 파생 클래스
* 2. 추가하는 값 KEY, IV, SALT 값
* 3. CBC : 블록 암호화 운영 모드 중 보안 성이 제일 높은 암호화 방법으로 가장 많이 사용 (IV 사용)
* 4. PKCS 5 : 8 바이트 패딩 (데이터 길이가 모자라다면 8 바이트까지 마지막 값 기준 채우고, 8 바이트 이상인 경우 뒤에 8바이트 패딩 추가)
* 5. PKCS 7 : 16 바이트 패딩 (데이터 길이가 모자라다면 16 바이트까지 마지막 값 기준 채우고, 16 바이트 이상인 경우 뒤에 8바이트 패딩 추가)
* 6. 참고 사이트 (aos) : https://www.tabnine.com/code/java/methods/javax.crypto.spec.PBEKeySpec/%3Cinit%3E
* 7. 참고 사이트 (ios) : https://gist.github.com/hfossli/7165dc023a10046e2322b0ce74c596f8
* // -----------------------------------------
* */
/** TODO [결과 출력 예시]
W///===========//: ================================================
I/: [C_AES256 >> encrypt() :: AES 암호화 인코딩 수행 실시]
--------------------
[secretKey :: 0123456789abcdef0123456789abcdef]
--------------------
[iv [string] :: 0123456789abcdef0123456789abcdef]
[iv [byte] :: [1, 35, 69, 103, -119, -85, -51, -17, 1, 35, 69, 103, -119, -85, -51, -17]]
I/: [iv [hex] :: 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF ]
--------------------
[salt [string] :: 0123456789abcdef0123456789abcdef]
[salt [byte] :: [1, 35, 69, 103, -119, -85, -51, -17, 1, 35, 69, 103, -119, -85, -51, -17]]
I/: [salt [hex] :: 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF ]
--------------------
[keyLength :: 32]
--------------------
[iterationCount :: 1000]
--------------------
[원본 :: hello]
[인코딩 :: 0yHy16m2dy5OpZH2+NX/4w==
]
W///===========//: ================================================
W///===========//: ================================================
I/: [C_AES256 >> decrypt() :: AES 암호화 디코딩 수행 실시]
--------------------
[secretKey :: 0123456789abcdef0123456789abcdef]
--------------------
[iv [string] :: 0123456789abcdef0123456789abcdef]
[iv [hex] :: [1, 35, 69, 103, -119, -85, -51, -17, 1, 35, 69, 103, -119, -85, -51, -17]]
I/: [iv [hex] :: 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF ]
--------------------
[salt [string] :: 0123456789abcdef0123456789abcdef]
[salt [hex] :: [1, 35, 69, 103, -119, -85, -51, -17, 1, 35, 69, 103, -119, -85, -51, -17]]
I/: [salt [hex] :: 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF ]
--------------------
[keyLength :: 32]
--------------------
[iterationCount :: 1000]
--------------------
[원본 :: 0yHy16m2dy5OpZH2+NX/4w==
]
[디코딩 :: hello]
W///===========//: ================================================
*/
// TODO [전역 변수 선언 부분]
public static final String secretKey = "0123456789abcdef0123456789abcdef"; // [32 바이트]
//public static final String ivKey = "0123456789abcdef";
public static final String ivKey = "0123456789abcdef0123456789abcdef"; // [32 바이트]
//public static final byte[] iv = ivKey.getBytes(); // [16 바이트]
public static final byte[] iv = C_Util.HexUtil_To_ByteArray(ivKey); // [16 바이트]
public static final String saltKey = "0123456789abcdef0123456789abcdef";
//public static final byte[] salt = saltKey.getBytes(); // [random byte]
public static final byte[] salt = C_Util.HexUtil_To_ByteArray(saltKey); // [random byte]
public static final String padding = "AES/CBC/PKCS7Padding"; // [알고리즘]
public static final int iterationCount = 1000;
public static final int keyLength = 256; // [32 length]
public static final String algo = "PBKDF2WithHmacSHA1"; // [알고리즘]
public static final String secretKeySpecType = "AES"; // [타입]
// TODO [AES256 base64 데이터 인코딩 수행]
public static String encrypt(String strToEncrypt) {
String returnData = "";
try {
// [iv 지정 : iv hex]
IvParameterSpec ivspec = new IvParameterSpec(iv);
// [알고리즘 지정]
SecretKeyFactory factory = SecretKeyFactory.getInstance(algo);
// [KeySpec : salt hex]
KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt, iterationCount, keyLength);
SecretKey tmp = factory.generateSecret(spec);
// [SecretKeySpec : 인코딩, 디코딩 수행에서 AES 지정]
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), secretKeySpecType); // [인코딩, 디코딩 수행에서 AES 지정]
// [Cipher]
Cipher cipher = Cipher.getInstance(padding); // [인코딩, 디코딩 수행에서 필요한 패딩 지정]
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec); // [KeySpec + iv]
returnData = Base64.encodeToString(cipher.doFinal(strToEncrypt.getBytes()), 0); // [base64 결과 반환 데이터]
} catch (Exception e) {
//e.printStackTrace();
}
Log.i("---","---");
Log.w("//===========//","================================================");
Log.i("","\n"+"[C_AES256 >> encrypt() :: AES 암호화 인코딩 수행 실시]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[secretKey :: "+String.valueOf(secretKey)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[iv [string] :: "+String.valueOf(ivKey)+"]");
Log.i("","\n"+"[iv [byte] :: "+Arrays.toString(iv)+"]");
Log.i("","\n"+"[iv [hex] :: "+C_Util.convert_ByteArray_To_HexString(iv)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[salt [string] :: "+String.valueOf(saltKey)+"]");
Log.i("","\n"+"[salt [byte] :: "+Arrays.toString(salt)+"]");
Log.i("","\n"+"[salt [hex] :: "+C_Util.convert_ByteArray_To_HexString(salt)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[keyLength :: "+String.valueOf(keyLength/8)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[iterationCount :: "+String.valueOf(iterationCount)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[원본 :: "+String.valueOf(strToEncrypt)+"]");
Log.i("","\n"+"[인코딩 :: "+String.valueOf(returnData)+"]");
Log.w("//===========//","================================================");
Log.i("---","---");
return returnData;
}
// TODO [AES256 base64 데이터 디코딩 수행]
public static String decrypt(String strToDecrypt) {
String returnData = "";
try {
// [iv 지정 : iv hex]
IvParameterSpec ivspec = new IvParameterSpec(iv);
// [알고리즘 지정]
SecretKeyFactory factory = SecretKeyFactory.getInstance(algo);
// [KeySpec : salt hex]
KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt, iterationCount, keyLength);
SecretKey tmp = factory.generateSecret(spec);
// [SecretKeySpec : 인코딩, 디코딩 수행에서 AES 지정]
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), secretKeySpecType); // [인코딩, 디코딩 수행에서 AES 지정]
// [Cipher]
Cipher cipher = Cipher.getInstance(padding); // [인코딩, 디코딩 수행에서 필요한 패딩 지정]
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec); // [KeySpec + iv]
returnData = new String(cipher.doFinal(Base64.decode(strToDecrypt, 0))); // [원본 데이터 반환]
} catch (Exception e) {
//e.printStackTrace();
}
Log.i("---","---");
Log.w("//===========//","================================================");
Log.i("","\n"+"[C_AES256 >> decrypt() :: AES 암호화 디코딩 수행 실시]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[secretKey :: "+String.valueOf(secretKey)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[iv [string] :: "+String.valueOf(ivKey)+"]");
Log.i("","\n"+"[iv [hex] :: "+Arrays.toString(iv)+"]");
Log.i("","\n"+"[iv [hex] :: "+C_Util.convert_ByteArray_To_HexString(iv)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[salt [string] :: "+String.valueOf(saltKey)+"]");
Log.i("","\n"+"[salt [hex] :: "+Arrays.toString(salt)+"]");
Log.i("","\n"+"[salt [hex] :: "+C_Util.convert_ByteArray_To_HexString(salt)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[keyLength :: "+String.valueOf(keyLength/8)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[iterationCount :: "+String.valueOf(iterationCount)+"]");
Log.i("","\n"+"--------------------");
Log.i("","\n"+"[원본 :: "+String.valueOf(strToDecrypt)+"]");
Log.i("","\n"+"[디코딩 :: "+String.valueOf(returnData)+"]");
Log.w("//===========//","================================================");
Log.i("---","---");
return returnData;
}
} // TODO [클래스 종료]
반응형
'Android' 카테고리의 다른 글
Comments