Last active
September 12, 2023 12:40
-
-
Save JosiasSena/3bf4ca59777f7dedcaf41a495d96d984 to your computer and use it in GitHub Desktop.
Encryptor and Decryptor for data encryption.decryption using the Android KeyStore.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
_____ _____ _ | |
| __ \ / ____| | | | |
| | | | ___| | _ __ _ _ _ __ | |_ ___ _ __ | |
| | | |/ _ \ | | '__| | | | '_ \| __/ _ \| '__| | |
| |__| | __/ |____| | | |_| | |_) | || (_) | | | |
|_____/ \___|\_____|_| \__, | .__/ \__\___/|_| | |
__/ | | | |
|___/|_| | |
*/ | |
class DeCryptor { | |
private static final String TRANSFORMATION = "AES/GCM/NoPadding"; | |
private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; | |
private KeyStore keyStore; | |
DeCryptor() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, | |
IOException { | |
initKeyStore(); | |
} | |
private void initKeyStore() throws KeyStoreException, CertificateException, | |
NoSuchAlgorithmException, IOException { | |
keyStore = KeyStore.getInstance(ANDROID_KEY_STORE); | |
keyStore.load(null); | |
} | |
String decryptData(final String alias, final byte[] encryptedData, final byte[] encryptionIv) | |
throws UnrecoverableEntryException, NoSuchAlgorithmException, KeyStoreException, | |
NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IOException, | |
BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException { | |
final Cipher cipher = Cipher.getInstance(TRANSFORMATION); | |
final GCMParameterSpec spec = new GCMParameterSpec(128, encryptionIv); | |
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(alias), spec); | |
return new String(cipher.doFinal(encryptedData), "UTF-8"); | |
} | |
private SecretKey getSecretKey(final String alias) throws NoSuchAlgorithmException, | |
UnrecoverableEntryException, KeyStoreException { | |
return ((KeyStore.SecretKeyEntry) keyStore.getEntry(alias, null)).getSecretKey(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
______ _____ _ | |
| ____| / ____| | | | |
| |__ _ __ | | _ __ _ _ _ __ | |_ ___ _ __ | |
| __| | '_ \| | | '__| | | | '_ \| __/ _ \| '__| | |
| |____| | | | |____| | | |_| | |_) | || (_) | | | |
|______|_| |_|\_____|_| \__, | .__/ \__\___/|_| | |
__/ | | | |
|___/|_| | |
*/ | |
class EnCryptor { | |
private static final String TRANSFORMATION = "AES/GCM/NoPadding"; | |
private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; | |
private byte[] encryption; | |
private byte[] iv; | |
EnCryptor() { | |
} | |
byte[] encryptText(final String alias, final String textToEncrypt) | |
throws UnrecoverableEntryException, NoSuchAlgorithmException, KeyStoreException, | |
NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IOException, | |
InvalidAlgorithmParameterException, SignatureException, BadPaddingException, | |
IllegalBlockSizeException { | |
final Cipher cipher = Cipher.getInstance(TRANSFORMATION); | |
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(alias)); | |
iv = cipher.getIV(); | |
return (encryption = cipher.doFinal(textToEncrypt.getBytes("UTF-8"))); | |
} | |
@NonNull | |
private SecretKey getSecretKey(final String alias) throws NoSuchAlgorithmException, | |
NoSuchProviderException, InvalidAlgorithmParameterException { | |
final KeyGenerator keyGenerator = KeyGenerator | |
.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE); | |
keyGenerator.init(new KeyGenParameterSpec.Builder(alias, | |
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) | |
.setBlockModes(KeyProperties.BLOCK_MODE_GCM) | |
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) | |
.build()); | |
return keyGenerator.generateKey(); | |
} | |
byte[] getEncryption() { | |
return encryption; | |
} | |
byte[] getIv() { | |
return iv; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
_____ _ _ _ | |
/ ____| | | | | | | | |
| (___ __ _ _ __ ___ _ __ | | ___ | | | |___ __ _ __ _ ___ | |
\___ \ / _` | '_ ` _ \| '_ \| |/ _ \ | | | / __|/ _` |/ _` |/ _ \ | |
____) | (_| | | | | | | |_) | | __/ | |__| \__ \ (_| | (_| | __/ | |
|_____/ \__,_|_| |_| |_| .__/|_|\___| \____/|___/\__,_|\__, |\___| | |
| | __/ | | |
|_| |___/ | |
*/ | |
public class MainActivity extends AppCompatActivity { | |
private static final String TAG = MainActivity.class.getSimpleName(); | |
private static final String SAMPLE_ALIAS = "MYALIAS"; | |
@BindView (R.id.toolbar) | |
Toolbar toolbar; | |
@BindView (R.id.ed_text_to_encrypt) | |
EditText edTextToEncrypt; | |
@BindView (R.id.tv_encrypted_text) | |
TextView tvEncryptedText; | |
@BindView (R.id.tv_decrypted_text) | |
TextView tvDecryptedText; | |
private EnCryptor encryptor; | |
private DeCryptor decryptor; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
ButterKnife.bind(this); | |
setSupportActionBar(toolbar); | |
encryptor = new EnCryptor(); | |
try { | |
decryptor = new DeCryptor(); | |
} catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | | |
IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
@OnClick ({R.id.btn_encrypt, R.id.btn_decrypt}) | |
public void onClick(final View view) { | |
final int id = view.getId(); | |
switch (id) { | |
case R.id.btn_encrypt: | |
encryptText(); | |
break; | |
case R.id.btn_decrypt: | |
decryptText(); | |
break; | |
} | |
} | |
private void decryptText() { | |
try { | |
tvDecryptedText.setText(decryptor | |
.decryptData(SAMPLE_ALIAS, encryptor.getEncryption(), encryptor.getIv())); | |
} catch (UnrecoverableEntryException | NoSuchAlgorithmException | | |
KeyStoreException | NoSuchPaddingException | NoSuchProviderException | | |
IOException | InvalidKeyException e) { | |
Log.e(TAG, "decryptData() called with: " + e.getMessage(), e); | |
} catch (IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) { | |
e.printStackTrace(); | |
} | |
} | |
private void encryptText() { | |
try { | |
final byte[] encryptedText = encryptor | |
.encryptText(SAMPLE_ALIAS, edTextToEncrypt.getText().toString()); | |
tvEncryptedText.setText(Base64.encodeToString(encryptedText, Base64.DEFAULT)); | |
} catch (UnrecoverableEntryException | NoSuchAlgorithmException | NoSuchProviderException | | |
KeyStoreException | IOException | NoSuchPaddingException | InvalidKeyException e) { | |
Log.e(TAG, "onClick() called with: " + e.getMessage(), e); | |
} catch (InvalidAlgorithmParameterException | SignatureException | | |
IllegalBlockSizeException | BadPaddingException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If someone needs it, I have created Example app for this code: https://github.com/luskan/EncryptDecryptApp