My Android app need to encrypt a file so that it can decrypt and read it
later. This should not be decrypt-able by anybody else other than the app,
even user - in other words, it is application secret data.
Following is how I am doing the encryption and decryption. This works most
of the time, but some times for some users this is failing. It is not
specific to a particular handset (Nexus7, Samsung, Motorola, HTC -- all
types are reporting this issue), but not all users are experiencing it.
Only some users occasionally.
Here is the relevant code:
encrypt() {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
final KeyStore.PrivateKeyEntry entry;
if (!ks.containsAlias(CERT_ALIAS)) {
Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
cal.add(Calendar.YEAR, 50);
Date end = cal.getTime();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA",
"AndroidKeyStore");
kpg.initialize(new KeyPairGeneratorSpec.Builder(getApplicationContext())
.setAlias(CERT_ALIAS)
.setStartDate(now)
.setEndDate(end)
.setSerialNumber(BigInteger.valueOf(1))
.setSubject(new X500Principal("CN=" + CERT_ALIAS))
.build());
KeyPair kp = kpg.generateKeyPair();
}
entry = (KeyStore.PrivateKeyEntry) ks.getEntry(
CERT_ALIAS, null);
pub = entry.getCertificate().getPublicKey();
// use the pub key to encrypt}
decrypt() {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
final KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)
ks.getEntry(
CERT_ALIAS, null);
PrivateKey key1 = entry.getPrivateKey();
// use the private key to decrypt}
This code sometimes throws
java.lang.RuntimeException: error:0D07207B:asn1 encoding
routines:ASN1_get_object:header too long
at com.android.org.conscrypt.NativeCrypto.ENGINE_load_private_key(Native Method)
at
com.android.org.conscrypt.OpenSSLEngine.getPrivateKeyById(OpenSSLEngine.java:66)
at android.security.AndroidKeyStore.engineGetKey(AndroidKeyStore.java:86)
at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:372)
at java.security.KeyStore.getEntry(KeyStore.java:644)
So I modified encrypt() to first try to get the entry and if it raises
exception, generate new key pair.
final KeyStore.PrivateKeyEntry entry = null;if (ks.containsAlias(CERT_ALIAS)) {
try {
entry = (KeyStore.PrivateKeyEntry) ks.getEntry(
CERT_ALIAS, null);
} catch (Exception e) {
}}if (entry == null) {
//generate new key pair}
But even this is failing sometimes with the following exception.
java.lang.IllegalStateException: could not generate key in keystore
at
android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:100)
at
java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275)
1. What am I doing wrong?
2. How do I fix it/work around it?
3. Before I generate new pair, should I delete the entry?
(KeyStore.deleteEntry())
4. Does this indicate the files (encrypted, wrapped secret key) are
tampered?
5. Does this happen on rooted devices or encrypted devices or when user
changes lock screen PIN/ password?
I posted this on Stack Overflow, but thought this might be better place
hence posting here.
http://stackoverflow.com/questions/23965300/android-keystore-getentry-and-generatekeypair-throw-exceptions-sometimes
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
---
You received this message because you are subscribed to the Google Groups
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.