Notice
Recent Posts
Recent Comments
Link
투케이2K
465. (Android/Java) KeyStore 키스토어 사용해 X.509 인증서 생성 및 public key , private key 사용해 인코딩 , 디코딩 수행 실시 본문
Android
465. (Android/Java) KeyStore 키스토어 사용해 X.509 인증서 생성 및 public key , private key 사용해 인코딩 , 디코딩 수행 실시
투케이2K 2023. 1. 24. 22:07[개발 환경 설정]
개발 툴 : AndroidStudio
[소스 코드]
// -------------------------------------
// [로직 처리 실시]
// -------------------------------------
try {
/**
* ----------------------------------
* [요약 설명]
* ----------------------------------
* 1. KeyStore 시스템은 승인되지 않은 접근에 대해 중요한 데이터를 보호하기 위한 암호화 저장 공간입니다
*
* - KeyStore 는 디바이스에서의 승인되지 않은 접근에 대해 이들 제한을 강제함으로써 승인되지 않은 접근에 대한 위협을 줄여줍니다
* ----------------------------------
* 2. KeyStore 시스템은 Android 4.0(API 수준 14)에서 도입된 KeyChain API 에서 사용됩니다
* ----------------------------------
* 3. KeyStore 는 Encryption / Decryption (암 / 복호화) 및 Digital Signature (전자서명) 에 사용되는 Private Key (개인키), Public Key (공개키) 와 Certificate (인증서) 를 제공 합니다
* ----------------------------------
* 4. KeyStore 에 데이터 암호화 및 복호화를 수행 할 때 AES, RSA 등 알고리즘을 선택해서 사용할 수 있으며, AES 는 마시멜로 이상 버전에서 사용할 수 있습니다
* ----------------------------------
* 5. 해당 로직 :
*
* - X.509 공개키 인증서 생성
*
* - keyStore 에 인증서 저장
*
* - keyStore 에 저장된 인증서 호출
*
* - 데이터 암호화를 수행하기 위해 인증서 public key 확인
*
* - 데이터 암호화 수행
*
* - 데이터 복호화를 수행하기 위해 인증서 private key 확인
*
* - 데이터 복호화 수행
* ----------------------------------
* 6. 참고 사이트 :
*
* https://developer.android.com/training/articles/keystore?hl=ko
*
* https://www.tabnine.com/code/java/classes/android.security.keystore.KeyGenParameterSpec$Builder
*
* https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec
* ----------------------------------
* */
// [생성할 인증서 정보 및 유효 일자 정의 실시]
String KEY_ALIAS = "PrivateKeyTwok";
String AndroidKeyStore = "AndroidKeyStore";
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 20);
// [AlgorithmParameterSpec 사용해 인증서 정보 정의]
AlgorithmParameterSpec spec = null;
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
spec = new KeyGenParameterSpec.Builder(KEY_ALIAS, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setCertificateSubject(new X500Principal("CN=" + KEY_ALIAS + " CA Certificate"))
.setCertificateSerialNumber(BigInteger.ONE)
.setCertificateNotBefore(start.getTime())
.setCertificateNotAfter(end.getTime())
.setBlockModes(KeyProperties.BLOCK_MODE_ECB)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.build();
}
else {
spec = new KeyPairGeneratorSpec.Builder(getApplicationContext())
.setAlias(KEY_ALIAS)
.setSubject(new X500Principal("CN=" + KEY_ALIAS + " CA Certificate"))
.setSerialNumber(BigInteger.ONE)
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
}
// [비대칭 암호화 새 개인 키 생성 및 KeyStore 에 저장 실시]
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);
kpg.initialize(spec);
KeyPair kp = kpg.generateKeyPair();
// [Keystore 로드]
KeyStore keyStore = KeyStore.getInstance(AndroidKeyStore);
keyStore.load(null);
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
Certificate certificate = keyStore.getCertificate(KEY_ALIAS); // 인증서 정보
// [데이터 암호화 및 복호화 수행에 필요한 형식 지정]
String transformat = "RSA/ECB/PKCS1Padding";
// [데이터 암호화 수행]
RSAPublicKey pubKey = (RSAPublicKey) keyEntry.getCertificate().getPublicKey(); // [암호화에 사용하는 공개키]
Cipher endcode_Cipher = Cipher.getInstance(transformat);
endcode_Cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte encode[] = endcode_Cipher.doFinal("hello".getBytes());
String encodeData = Base64.encodeToString(encode, 0);
// [데이터 복호화 수행]
PrivateKey privateKey = keyEntry.getPrivateKey(); // [복호화에 사용하는 개인키]
Cipher decode_Cipher = Cipher.getInstance(transformat);
decode_Cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte decode[] = Base64.decode(encodeData, Base64.DEFAULT);
String decodeData = new String(decode_Cipher.doFinal(decode), "UTF-8");
// [로그 출력 실시]
S_Log.ltd("================================================");
S_Log.cnt("["+ACTIVITY_NAME+" >> "+C_Util.getNowMethod(1)+" :: 로그 출력 실시]");
S_Log.cnt("[keyStore isKeyEntry :: "+String.valueOf(keyStore.isKeyEntry(KEY_ALIAS))+"]");
S_Log.cnt("[certificate getType :: "+String.valueOf(certificate.getType())+"]");
S_Log.cnt("[pubKey :: "+String.valueOf(pubKey.getAlgorithm())+"]");
S_Log.cnt("[privateKey :: "+String.valueOf(privateKey.getAlgorithm())+"]");
S_Log.cnt("[certificate :: "+String.valueOf(certificate.toString())+"]");
S_Log.cnt("[encodeData :: "+String.valueOf(encodeData)+"]");
S_Log.cnt("[decodeData :: "+String.valueOf(decodeData)+"]");
S_Log.lbd("================================================");
}
catch (Exception e){
e.printStackTrace();
}
[결과 출력]
반응형
'Android' 카테고리의 다른 글
Comments