If your encryption is key is common then your data isn’t really being protected. Here’s what I do to send encrypted datagram packets:
You need a way to safely and securely transmit the secret keys used for encryption and decryption. This is an already solved problem. I have the Client connect to the Server using a TLS/SSL TCP connection through an open source library. Don’t be like Yik Yak and make sure if you need serverside or clientside authentication (or both) that you do it. Man in the middle attacks are pretty trivial to conduct nowadays and it’s just good practice.
Now you have a connection where you can transmit information with a good guarantee that your key is actually from the correct server, hasn’t been intercepted, and hasn’t been modified on the way. You should do any user authentication over this connection and when you’re done, have the server send unique send/receive keys to the client and maybe a session key as well. Use the session key for the client to identity themselves to the UDP server. Can’t trust the client to just say who they are. They only person who could possibly have that session key was the client who originally connected to the TCP server.
The UDP server could be on the same process or even on a separate computer. Get the send/receive keys and session key to the UDP server though a secure means. (Use TLS/SSL with client/server authentication like we did above.)
Have the client connect to the UDP server using the session key to identify themselves. At this point the client and server can encrypt/decrypt any messages. I also use Cipher.getInstance for the actual encryption. I’ll use two of them, one each for encrypt and decrypt.
//send cipher
encodedKey = NetworkUtility.decodeBASE64String(sendKey);
SecretKey originalKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
sendCiph = Cipher.getInstance("AES/CTR/PKCS5PADDING");
sendCiph.init(Cipher.ENCRYPT_MODE, originalKey, ivspec);
//receive cipher
encodedKey = NetworkUtility.decodeBASE64String(receiveKey);
originalKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
receiveCiph = Cipher.getInstance("AES/CTR/PKCS5PADDING");
receiveCiph.init(Cipher.DECRYPT_MODE, originalKey, ivspec);
I’m not really a security expert but I think this is a pretty secure setup. If anyone does see any issues I missed let me know. The worst security setups are the ones you think are secure through obscurity. Show it to the public and let them pick holes in it. The best setups are the ones where even if an attackers knows everything about it, they still can’t get in.