Let’s say I have some sensitive data, e. g. an API key users have to add. I now want to send this key to the server and prevent any man-in-the-middle attacks. I’m using HTTPS for the communication, but I’m not sure if this is “enough” in such a scenario.
Would you recommend adding another encryption layer that is only known to the client and the server, and if so, what is the best way to implement this? The server should still be able to decrypt the key when needed.
API keys and other passwords are usually set as environment variables, that are only serverside. For example, here is adding some new environment variables at various platforms:
If there is some need to copy some environment variable to clientside, it’s possible by setting public variable:
Or if that environment variable is only needed serverside, it can stay at environment varible, or copied to private variable like Meteor.settings.headerLoginId .
API keys are usually needed to exist unencrypted at serverside.
3) User accounts
For user accounts, Meteor accounts packages save password in hashed format to database.
Before showing any sensitive data, it’s useful to check is user logged in:
if (Meteor.user()) {
...
}
4) Admin Panel
If at Admin Panel UI it’s needed to save some new password to database, it’s useful to just save it, for example with Meteor Method, but not load it back, not adding it to PubSub minimongo content.
import CryptoJS from 'crypto-js'. // this library is now deprectated but ... "Nowadays, NodeJS and modern browsers have a native Crypto module. " - Check the NPM details.
const passphrase = process.env.PHRASE // or your safe way to store a pass. This can also be a userId, session id, anything that you can pick up on the server for the same user. The userId can also be altered at both ends so that you cannot reverse engineer it.
return CryptoJS.AES.encrypt(string, passphrase).toString()
Decrypt
import CryptoJS from 'crypto-js'
const passphrase = '' // same as above
const bytes = CryptoJS.AES.decrypt(string, passphrase)
return bytes.toString(CryptoJS.enc.Utf8)
You can generate a key pair: Public key + Private key.
Send the Private Public key to client, client will use this key to encrypt data then send to server.
On the server side, use private key to decrypt the data.
// Edit: Send the public key to the client, not the private one.