Notice
Recent Posts
Recent Comments
Link
투케이2K
219. (AndroidStudio/android/java) aes 암호화 파생 인코딩 , 디코딩 수행 실시 - secretkey , iv , salt 본문
Android
219. (AndroidStudio/android/java) aes 암호화 파생 인코딩 , 디코딩 수행 실시 - secretkey , iv , salt
투케이2K 2021. 11. 18. 09:24[개발 환경 설정]
개발 툴 : AndroidStudio
개발 언어 : java
[소스 코드]
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 :: 0123456789abcdef]
[salt :: 0123456789abcdef0123456789abcdef]
[keyLength :: 32]
[iterationCount :: 10000]
[원본 :: hello]
[인코딩 :: 4KpINm+YV8sEqzj8ccXIkw==
]
W///===========//: ================================================
W///===========//: ================================================
I/: [C_AES256 >> decrypt() :: AES 암호화 디코딩 수행 실시]
[secretKey :: 0123456789abcdef0123456789abcdef]
[iv :: 0123456789abcdef]
[salt :: 0123456789abcdef0123456789abcdef]
[keyLength :: 32]
[iterationCount :: 10000]
[원본 :: 4KpINm+YV8sEqzj8ccXIkw==
]
[디코딩 :: hello]
W///===========//: ================================================
*/
// TODO [전역 변수 선언 부분]
public static final String secretKey = "0123456789abcdef0123456789abcdef"; // [32 바이트]
public static final String ivKey = "0123456789abcdef";
public static final byte[] iv = ivKey.getBytes(); // [16 바이트]
public static final String saltKey = "0123456789abcdef0123456789abcdef";
public static final byte[] salt = saltKey.getBytes(); // [random byte]
public static final String padding = "AES/CBC/PKCS7Padding"; // [알고리즘]
public static final int iterationCount = 10000;
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 지정]
IvParameterSpec ivspec = new IvParameterSpec(iv);
// [알고리즘 지정]
SecretKeyFactory factory = SecretKeyFactory.getInstance(algo);
// [KeySpec]
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"+"[secretKey :: "+String.valueOf(secretKey)+"]");
Log.i("","\n"+"[iv :: "+String.valueOf(ivKey)+"]");
Log.i("","\n"+"[salt :: "+String.valueOf(saltKey)+"]");
Log.i("","\n"+"[keyLength :: "+String.valueOf(keyLength/8)+"]");
Log.i("","\n"+"[iterationCount :: "+String.valueOf(iterationCount)+"]");
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 지정]
IvParameterSpec ivspec = new IvParameterSpec(iv);
// [알고리즘 지정]
SecretKeyFactory factory = SecretKeyFactory.getInstance(algo);
// [KeySpec]
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"+"[secretKey :: "+String.valueOf(secretKey)+"]");
Log.i("","\n"+"[iv :: "+String.valueOf(ivKey)+"]");
Log.i("","\n"+"[salt :: "+String.valueOf(saltKey)+"]");
Log.i("","\n"+"[keyLength :: "+String.valueOf(keyLength/8)+"]");
Log.i("","\n"+"[iterationCount :: "+String.valueOf(iterationCount)+"]");
Log.i("","\n"+"[원본 :: "+String.valueOf(strToDecrypt)+"]");
Log.i("","\n"+"[디코딩 :: "+String.valueOf(returnData)+"]");
Log.w("//===========//","================================================");
Log.i("---","---");
return returnData;
}
} // TODO [클래스 종료]
[결과 출력]
반응형
'Android' 카테고리의 다른 글
Comments