I know this question is So popular in StackOverflow that How AES 256 implemented in Android, but the main problem is No any solution gives the exact encryption and decryption of AES 256. All codes are explained through Key Length of 128 and 256 which is not correct.
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(256, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
But I need different from this, which AES 256 implementation not as the 256 key length. Please suggest me the right solution regarding the same.
Thanks in advance.
If the keying material you have is a password, you should use PBKDF2. If not, it's probably sufficient just to take the SHA-256 hash of the keying material, which will be 256-bits. For a 128-bit key, just use half the hash.
Note that using keying material that is less than 100 bits is extremely inadvisable.
AES256 always uses a 256 bit key. If your key material has a different length, you can use the output of a hash function, such as SHA-256 to get a 256 bit key.
But if your key material has an entropy of less then 256 bits, that obviously means that you won't get 256 bits of security. Practical security suffers once you get significantly below 128 bits of security.
If your key material is a password, use a key-derivation-function such as PBKDF2 to get the key. It's deliberately slow, in order to increase the security with relatively low entropy passwords.
Related
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.
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.
I am using a 128-bit AES cipher algorithm. But the program takes a long time, since the files to encrypt are big.
I was wondering if there is a more light cipher algorithm to use in Android. I can't find a list of supported ciphers in Android.
Have you tried to use shorter keys with AES instead? You can try OpenSSL build as native code, but I guess dalvik already uses optimized libraries, I don't think it will help. There are good reasons AES takes some time, by choosing something faster, you will have to lower real security.
I suggest you should not encrypt whole file if you need speed. Instead, encrypt only header or parts of file, without which rest of file is not useful. However it depends on what data you are encrypting and will not work for generic data files.
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
This is my code for AES.
Under Gingerbread I get following error after encrypting the data on 2.2 then trying to decrypt on 2.3:
Caused by: javax.crypto.BadPaddingException: pad block corrupted
at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:715)
at javax.crypto.Cipher.doFinal(Cipher.java:1090)
at com.citc.wallet.util.security.SimpleCrypto.decrypt(SimpleCrypto.java:63)
... 21 more
I have found some posts saying that SecureRandom is producing different results under different systems:
BouncyCastle AES error when upgrading to 1.45
How do I avoid this problem on 2.3?
Can I somehow force 2.3 to use the same SecureRandom class?
Do I need to use some portable encryption method and if so what?
The answer is that you shouldn't really be doing what you are doing at all. Here is the culprit:
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
You should never pad your key with some un-predictable random value because you will need to recreate this same exact key later on. Here are some key lines from the android docs
"Seeding SecureRandom may be insecure"
Although it is common practice to seed
Random with the current time, that is
dangerous with SecureRandom since that
value is predictable to an attacker
and not appropriate for secure use.
Anyway, I know your argument will be that you are just "padding" the key and the security of what you are doing is not a big deal.
If you are going to accept keys of 128 bits for 192 or 256 bit implementations, then you must implement a repeatable method of expanding the key to 192 or 256 bits. You can even add all 0's to the key if you wanted to, but the key really is that it must be done in some way that you can repeat it on every system.
In any case, you may also want to consider that what you are doing may be used on systems other than Android. In those cases, using a more "portable" method to expand a key should be chosen.