I can generate a key to be stored in the Android Keystore like so:
private static final String AndroidKeyStore = "AndroidKeyStore";
private static final String AES_MODE = "AES/GCM/NoPadding";
keyStore = KeyStore.getInstance(AndroidKeyStore);
keyStore.load(null);
if (!keyStore.containsAlias(KEY_ALIAS)) {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, AndroidKeyStore);
keyGenerator.init(
new KeyGenParameterSpec.Builder(KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setRandomizedEncryptionRequired(false)
.build());
keyGenerator.generateKey();
}
Similarly, I can retrieve it like so:
keyStore.getKey(KEY_ALIAS, null);
I know that the getKey() function returns a Key object, but I haven't found a way to reveal the key itself. It does not seem to have a toString() or getBytes() or something like that.
How can I get the bytes of the key, or at least print out the string version of it? Is it even possible?
The "AndroidKeyStore" is specifically designed to make this impossible or at least very difficult. There is a more complete discussion here, but in summary:
Android Keystore system protects key material from unauthorized use. Firstly, Android Keystore mitigates unauthorized use of key material outside of the Android device by preventing extraction of the key material from application processes and from the Android device as a whole.
Continuing along the lines of your example, the following additional lines of code:
Key key = keyStore.getKey(KEY_ALIAS, null);
String algorithm = key.getAlgorithm();
String format = key.getFormat();
byte[] encoded = key.getEncoded();
should cause key to be a valid non-null reference to Key object, algorithm
should return "AES", but format
should be null
as should encoded
.