As you've seen, encryption requires keys. Keys are just strings of data that are used to secure a message. Similar to how a password protects access to an online account, cryptographic keys protect a cryptographic message. A key can be a password, but typically when we talk about keys we're talking about longer, more secure strings of data.
For example, a randomly generated, 256-bit key, represented in hex, would look like this:
ddda0e759e1c1c8861f350752ce66eb972207570e0b0f9db1a405707f90b4e67
Keys can be used many times, but the less often a key is used, the less likely it is to become compromised. For this reason, single-use keys are often the most secure.
The biggest problem with single-use keys is that it's hard to remember a new key for each message. As a result, single-use keys can be inconvenient.
Single-use keys are best used in systems where a human doesn't need to remember what the key is. For example, maybe a new key can be generated by code for each message.
At Passly, each user's password vault has its own encryption key, and each time a user decrypts their vault, we generate a new key. Because the user doesn't need to remember the key, we can make it long and random, and we can frequently generate new keys.
Complete the generateRandomKey function. It accepts a length in bytes, and returns a random key of that length, formatted in a hex string.
randReader Rand instance.%x formatting verb.randReader.Read accepts a []byte slice, and fills it with random bytes: just make sure that the slice is the right length. It returns the number of bytes written, and an error. You don't need to worry about the number of bytes written, but you should check for an error.