Java – a better way to create AES keys than secure random

I need to send encrypted data from the Java client to the c# server Now I'm learning how to encrypt data using AES According to the accepted answer Android encryption / decryption with AES, I am doing the following:

byte[] keyStart = "qweroiwejrwoejlsifeoisrn".getBytes(); // Random character string

byte[] toEncrypt = myMessageString.getBytes();

keyGen = KeyGenerator.getInstance("AES");
sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
keyGen.init(128,sr);
SecretKey secretKey = keyGen.generateKey();
byte[] secretKeyByte = secretKey.getEncoded();

SecretKeySpec skeySpec = new SecretKeySpec(secretKeyByte,"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,skeySpec);
cipher.doFinal(toEncrypt);

Since the algorithm uses keystart and securerandom, I'm not sure if this can be decoded in c# or even in other Java programs without securerandom

Does this encryption / decryption only need to know the value of keystart, or because I use securerandom, do I need to pass other contents to decrypt?

Also, is there a better way to do this or this?

Solution

No, the whole idea that you should use securerandom to get keys from static data is pretty bad:

>The main function of securerandom is to generate random values. It should not be used as a generator of key stream; > Securerandom, when instantiated with "sha1prng", does not implement a well-defined algorithm. In fact, it is known that the algorithm will change, even from one sun JDK to another; > The "sha1prng" implementation provided by Oracle uses the initial seed as the seed, and others may just add the seed to the random pool

It is known that using "sha1prng" as a key derivation function will cause problems on multiple versions of Android and may fail on any other Java re

So what should you do?

>Use the new securerandom() or even better, keygenerator to generate a real random key. If you need a new random key, you don't need to seed the random number generator; > Directly provide the byte [] of the known key to the secretkeyspec, or use the hexadecimal decoder to decode it from hexadecimal (please note that the string instance is difficult to delete from memory, so do this only when there is no other method); > If you want to create a key from a password, use pbkdf2 (using more iterations than provided in the link); > If you want to create multiple keys from one key seed, use a true key based key derivation mechanism, such as hkdf (see below)

If seeds are generated by, for example, seeds, alternative 4.1 is preferred Key agreement algorithm, such as Diffie Hellman or ecdh

Note that for option 3, pbkdf2, you'd better keep only ASCII passwords This is because Oracle's pbkdf2 implementation does not use UTF - 8 encoding

As for option 4, I help add all good kbkdf to bouncy castle libraries, so if you can add bouncy castle to the classpath and / or the list of installed security providers, you don't need to implement kbkdf yourself At present, the best kbkdf may be hkdf If you cannot add bouncy castle to the classpath, you may want to use the leftmost byte of SHA-256 output instead of derived data as the "poor" KDF

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>