We are using Android 4.0.4 ICS in an enterprise context, and i am trying to understand how Android protects the Key Store, specifically the Certificates Private Key.
What Hashing Algorithm does it use?
Are there any good reference materials out there that i can present to my Security Architect?
Take a look at Nikolay Elenkov's articles on ICS KeyChain if you want to see how that API is implemented inside. There are three articles in the series, but the article on ICS Credential Storage Implementation tells you how the files are stored on disk.
keytool is a standard Java tool for managing a keystore and associated X.509 certificates.
See the documentation for more information; more specifically the section on supported algorithms:
The default key pair generation algorithm is "DSA". The signature
algorithm is derived from the algorithm of the underlying private key:
If the underlying private key is of type "DSA", the default signature
algorithm is "SHA1withDSA", and if the underlying private key is of
type "RSA", the default signature algorithm is "MD5withRSA". When
generating a DSA key pair, the key size must be in the range from 512
to 1024 bits, and must be a multiple of 64. The default key size for
any algorithm is 1024 bits.
Related
Good afternoon,
I need a little bit of help. I'm using QT6.4 to write an Android app that handles private keys.
I have no prior experience with QT or Android app development. This app stores an Ecdsa private key used to make signatures, the key is generated remotely. Currently I just store it in a text file but it doesn't seem like good security. I heard of Android keystore but I don't know if it's possible to use.
Any suggestions or examples?
Storing private key in plain text file seems insecure. Other apps could read it.
In Qt, there is no API to access the Android Keystore... So the best solution would be to access it in Java/Kotlin.
To add a custom Java class to an Qt Android application, and how to call it using the JNI convenience APIs in Qt, you can check the notifier example :
https://doc.qt.io/qt-6/qtcore-platform-androidnotifier-example.html
The most secure usage would be to generate the private key inside the Android Keystore, which doesn't allow to access it. To generate private keys in Keystore this is a good site to read:
https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec
If the key needs to generate remotely and you download it, then you have 2 possibilities:
Import the key into AndroidKeystore - start by reading: https://developer.android.com/reference/kotlin/android/security/keystore/KeyProtection
Generate a new private key and encrypt the key. Then store it in a file or any persistent place.
According to documentation for app developers AES_128 and AES_256 are supported from api 26. https://developer.android.com/reference/javax/crypto/Cipher. For example now I'm using AES(GCM mode) with 128 bit key. What is the difference between AES with 128 bit key and AES_128 ?
There is no difference between AES with a 128-bit key and AES_128.
As you can see in the docs you linked, previous to API 26 there existed one primitive for AES, with various padding options/modes of operation.
To make things simpler, in API 26+ there is now two primitives to disambiguate the usage of AES with either a definitive 128-bit or 256-bit key.
If you are using AES, you should opt for AES-256 GCM as it provides a authenticated encryption, ensuring that the ciphertext cannot be tampered with, without the recipients knowledge.
AES-GCM operates with a 32-bit counter, so unfortunately with the same key, nonce (IV) pair you can only safely encrypt ~ 64GB of data (2^39-256 bits).
If you want to move to an even safer cipher, I recommend XSalsa20 or XChaCha20, which provide a 192-bit nonce size, effectively allowing a practically "unlimited" amount of data to be encrypted with the same key, nonce pair.
AES_128 doesn't exists. However, constants in Java don't generally use the hyphen (-) character, so the underscore is used to indicate AES-128 (still a strange choice for a String if you ask me).
AES-128 is just AES configured to use a 128 bit key. Internally it uses a specific sub-key derivation and 10 rounds. AES-256 has a different sub-key derivation and uses 14 rounds. AES-192 (12 rounds) isn't used much, as it has an awkward key size and it doesn't fully protect against attacks that may be applicable to AES-128.
Practically speaking there may be two differences when it comes to general usage. First of all, the API may be able to select an implementation of 128 or 256 bits of AES before the init methods are called. Secondly, I presume that the init method only accepts 128 bit keys when you configure AES-128.
I'd like to leave the user the possibility to choice the encryption method, but for now I implemented just AES with SHA1PRNG. With AES/CBC/PKCS5Padding it doesn't work.
What does other encryption method work with android?
I have to encrypt data to store them in a db and then decrypt for show them.
The error returned:
java.security.NoSuchAlgorithmException: SecureRandom AES/CBC/PKCS5Padding implementation not found
here:
SecureRandom.getInstance( "AES/CBC/PKCS5Padding" );
Do you want to use a random number generator (which is what SecureRandom is for), or do you want to use an encryption algorithm (which is what AES is for)?
If you want an encryption algorithm (and its implementation), use the javax.crypto.Cipher class, which should support your AES/CBC/PKCS5Padding algorithm.
In principle you can use AES to build an RNG, too, but then you would not use CBC/PKCS5Padding, but something like ANSI X9.31. I don't think this is implemented in any Java and/or Android API for SecureRandom.
According to the reference it only supports SHA1PRNG, unless you install other providers.
See: http://developer.android.com/reference/java/security/SecureRandom.html
I'm using SpongyCastle (full implementation of BouncyCastle's crypto functions for Android) and I have a bks that contains a key of size 384. I'm trying to extract that key using the method KeyStore.getKey(alias, password) as you would any key in a keystore. But what I'm running into is the error
java.security.UnrecoverableKeyException: no match.
Doing a little bit of research indicates that it might be because the key size is too big for Android to handle which makes sense as my program gets the other keys of sizes 128 and 256 no problem. Normally in Java, this would be resolved by importing the "Unlimited Strength" JCE into the Java security folder but what about android? Can I import the unlimited strength JCE into android (my gut instinct is no) If not, are there any suggestions as to how to extract the key? SpongyCastle has solved a lot of my other issues, I'm hoping there's a SpongyCastle solution here too.
Thanks!
So after much wrestling with it, I figured out the problem.
I wasn't specifying a provider so my program defaulted to the default Android BouncyCastle. The minute I did
KeyStore ks = new KeyStore("BKS","SC");
as opposed to
KeyStore ks = new KeyStore("BKS");
it worked just fine and did not complain.
I am completely new to android. What I wanna do is, from a given textbox, I want to get the number, encrypt it with a key stored in the android app (which increments each time the user does the encryption) and then pass the ciphertext through sha1 and then print it back on the screen. Can anybody give me some basic help?
I don't understand what is incrementing, but I will give a shot.
You can use BouncyCastle (how to add bouncycastle algorithm to android) for the encryption, and then just use base64 on the SHA1 (which is weak) hash in order to have it be printable.
The only trick is how you get the key on the Android, your best bet may be to have it be generated on the device.