AES 암복호화
AES128 : 키값 16bytes
AES192 : 키값 24bytes
AES256 : 키값 32bytes
** ivBytes 값은 16bytes로 랜덤 키값으로 주로 사용한다.
AES256::iv 암호화
1. "991226" : aes256 encode 후 Base64 encode
2. 구분자 "::" 추가후 뒤에 iv 값 추가
ex) 65wUWQtaMSe8PJSBOmTCLA==::mchnuridyvpvrzsy
3. ex 전체 데이터 Base64로 재포장
최종결과 : R3hvQzJxWTFIc2o5bXQ3RDNpdmpLUT09OjpyZ294em5jcXZvZHpocWdw
import android.util.Base64;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES256Util {
//키값 32바이트: AES256 / 24바이트: AES192 / 16바이트: AES128
private static String secretKey = "HNUJAEBfB9ygAm4wGJZ2XV4qTzFg2XAA";
private static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
// random iv key 생성
public static String generateRandomPassword() {
SecureRandom random = new SecureRandom();
StringBuilder passwordBuilder = new StringBuilder();
while (passwordBuilder.length() < 16) {
int randomIndex = random.nextInt(LOWERCASE.length());
char randomChar = LOWERCASE.charAt(randomIndex);
passwordBuilder.append(randomChar);
}
return passwordBuilder.toString();
}
/**
* AES256::iv 암호화
* 1. "991226" : aes256 encode 후 Base64 encode
* 2. 구분자 "::" 추가후 뒤에 iv 값 추가
* ex) 65wUWQtaMSe8PJSBOmTCLA==::mchnuridyvpvrzsy
* 3. 전체 데이터 Base64로 재포장
* 최종결과 : R3hvQzJxWTFIc2o5bXQ3RDNpdmpLUT09OjpyZ294em5jcXZvZHpocWdw
* */
public static String encryptAES256(@NonNull Context context, String str) {
String ivString = generateRandomPassword();
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivString.getBytes());
SecretKeySpec newKey = null;
try {
newKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");
} catch (UnsupportedEncodingException e) {
DLog.e(new Exception(), e.getMessage());
}
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
} catch (InvalidKeyException| InvalidAlgorithmParameterException |NoSuchPaddingException | NoSuchAlgorithmException e) {
DLog.e(new Exception(), e.getMessage());
}
String encryptString = "";
try {
encryptString = Base64.encodeToString(cipher.doFinal(str.getBytes()), Base64.NO_WRAP)+"::"+ivString;
encryptString = Base64.encodeToString(encryptString.getBytes(), Base64.NO_WRAP);
} catch (IllegalBlockSizeException | BadPaddingException e) {
DLog.e(new Exception(), e.getMessage());
}
return encryptString;
}
/**
* AES256::iv 복호화
* */
public static String decryptAES256(@NonNull Context context, String str) {
byte[] textBytes = Base64.decode(str,Base64.DEFAULT);
String string = new String(textBytes);
int idx = string.indexOf("::");
String bodyBase64 = string.substring(0, idx);
byte[] message = Base64.decode(bodyBase64, Base64.DEFAULT);
byte[] ivBytes = string.substring(idx+2).getBytes();
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
SecretKeySpec newKey = null;
try {
newKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");
} catch (UnsupportedEncodingException e) {
DLog.e(new Exception(), e.getMessage());
}
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
} catch (InvalidKeyException| InvalidAlgorithmParameterException |NoSuchPaddingException | NoSuchAlgorithmException e) {
DLog.e(new Exception(), e.getMessage());
}
String decodeData = null;
try {
decodeData = new String(cipher.doFinal(message), "UTF-8");
} catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
DLog.e(new Exception(), e.getMessage());
}
return decodeData;
}
}
[사용방법]
String str = "aes256_test";
String encrypt = AES256Util.encryptAES256(this, str); // "R3hvQzJxWTFIc2o5bXQ3RDNpdmpLUT09OjpyZ294em5jcXZvZHpocWdw"
String decrypt = AES256Util.decryptAES256(this, encrypt); // "aes256_test"
'Android(Java)' 카테고리의 다른 글
[Java] Log 가독성있게 찍기 (0) | 2024.04.08 |
---|---|
[Java] ConstraintLayout LinearLayout Height 자동크기변경 (0) | 2024.04.05 |
[Java] 디바이스 정보가져오기[모델명,OS버전,Device ID] (0) | 2024.03.29 |
[Android] 금융권 안드로이드 프로젝트 내부망 세팅방법 (1) | 2024.03.29 |
[Android] 구버전 안드로이드 스튜디오 다운로드 링크 (0) | 2024.03.29 |