What you are trying to do is called key distribution. The distribution of keys requires that you use a secure channel. This could be:
- Symmetric using a password (but then you need to distribute the password securely, so it's a chicken and egg problem).
- A database is not considered a secure way to share keys
- SSL: Asymmetric encryption is one way to do this, but in this case, you could first implement SSL / TLS in your application. It is used in a similar way to HTTPS (in fact, it uses hybrid encryption to exchange a symmetric key that is then used with AES or another symmetric encryption, to exchange the data)
- Another option is to use a hardware token that contains the encryption key (for example, Yubikey). This can be used, for example, to perform mutual SSL authentication.
For your second part of your question:
- This is much debated, in general, depends on the case of use of your application and the amount of data it encrypts. The more data you encrypt, the faster you need to rotate them. But all this depends on the algorithm, etc. (For example, AES GCM mode loses protection if more than 64 GB is encrypted in the same key, see section 184.108.40.206 of NIST SP 800-38D). So there is not a single correct answer. If you opt for the SSL option, every 365 days is probably your best bet.
- Whether that variable is public or private does not matter. One thing to keep in mind is that, instead of using String, it must be a character array (if a managed language such as Java or .NET is used) to prevent the key from being downloaded to a memdump in case the machine block. The idea is to load the key before each encryption / decryption and then overwrite the variable with 0 once the operation is complete. This will reduce the likelihood that the key leaks.
Using SSL / TLS with anchor certificate in your application would be the easiest, since you can actually use a different and mutually agreed symmetric key for each session you set up with your client.