How to store sensitive data in AWS - amazon-web-services

So I'm new to the whole cloud computing infrastructure and I'm trying to grasp the best practices and today it came to my mind. How do I store sensitive data in AWS what services do I need to utilize and what architecture shall I build for it, I wrote a scenario down to further explain my question.
Let's say I have a user registration and I need from every user to input a secret key that I need to access some kind of 3rd party service on their behalf (let's assume that it's the only to access that service and no other way to access it) how do I store it in my database let's say RDS for example without compromising other IAM users from accessing the database but all they say is an encrypted secret key not the plain text.
I searched online and found some saying KMS and some saying Secrets Manager some saying Backend Encrypting and some says Frontend Encrypting which way shall I go with?
Whoever decides to answer this question thanks in advance but please elaborate as much as you can because I'm still trying the get the concepts and trying to leverage the "Cloud" capabilities as much as possible.

Two common approaches would be to encrypt the secret key at either a) the application level, or b) the database level. To encrypt the key inside your application, you would use some reliable encryption method, such as SHA-256 or SHA-512. The key would be encrypted and non accessible even before you write it out to your database as binary content. To encrypt at the database level, there are a number of options, depending on your particular database. If your RDBMS support encrypted columns, then, from your application, you may simply write out the secret key to its column. The database would then automatically handle encrypting on the way in, and also decrypting the secret key on the way out, when you go to read it.

Related

developing custodial vs non-custodial wallets

This is a very broad and general question so I'm going to specify my intended use case and branch several questions, mainly referring to the implementation of each approach.
In short, users using my wallet are going to constantly send to each other, and perhaps receive/send from/to other wallets and networks, and I'm mentioning this in case it could provide an overview of how transactions will take place in my app.
so to start with the custodial wallets:from what i know, most custodial wallets have 1 cold wallet and 1 hot wallet and a hot wallet to every user, so when a user creates an account keys are automatically generated to that user, but my question is how are the users' keys stored: is it in a normal db or do they do it in another way, and how does this model work like how do they technically use the cold and hot wallets.
moving to non-custodial wallets,i want to know basically the same thing, how and where are the users' keys stored? and how are they accessed? and in case i go with this approach i am still able to impose tx fees on tx happening on my app?
I hope I made sense in what I said, and I hope to check your answers, If you feel like you know an answer to some part of the question but not all that okay say what you know as any contribution would be great, and if anyone is up for a discord/zoom call i would really appreciate it. Thanks in advance, and please let me know in case you need extra info to answer.
custodial wallets
how are the users' keys stored
It depends on each app implementation. A good practice is to store sensitive data (such as private keys) in a secrets management system. It's usually an encrypted database with advanced access control - allowing access to groups of data based on user group policies, generating single-use or time-sensitive tokens for accessing the data, ... The application can then request the private key from the SMS using the user's unique token.
non-custodial wallets
how and where are the users' keys stored? and how are they accessed?
Software wallets (including browser extensions) usually store private keys in a file, located in your computer, encrypted by a master key. The master key can be for example the hash of your MetaMask password and some predefined salt. When you unlock the wallet by entering the correct password, the wallet software decrypts the file containing the actual private keys, and then it's able to use the private keys.
Hardware wallets store private keys on the device, encrypted by a master key as well (e.g. your device PIN and a salt). It's a common practice that private keys never leave the device. So the UI software usually sends a request to sign a raw transaction data to the device, the device then asks the user to enter their pin, performs the signature on the actual device and returns the signed transaction back to the UI software.

Is there any way to make a specific information on blockchain can only be queried by one specific account?

just want to know, is there any way to make specific information on the blockchain can only be queried by one specific account?
More exactly, I am thinking let the user put their information on chain and give specific account access, so only that account can query that information from chain.
I checked ZK-SNARK, seems like this algorithm is only for verify the information is correct without knowing any detail of the information. Seems like it cannot be used in this case
Any raw data placed on a blockchain is available to everyone on the network. This is one of the fundamental requirements to ensure that multiple distributed and decentralized nodes are able to verify a shared state.
However, the data placed on chain does not need to be "transparent" to every user. You could, for example, encrypt some data and place it on the blockchain. Of course everyone will be able to see your encrypted data, but only with the decryption key would they be able to make sense of it.
With the assumption that the blockchain you use has some built in public key cryptography for account authentication, you could use the private key as your encryption/decryption key. Thus only "that account" would have acces to that file (...anyone who knows the private key that corresponds to that account).
However, all of this logic would need to exist "off-chain". If you submit a transaction with raw data, and expect the blockchain to do the encryption/decryption for you, anyone who runs a node would be able to see that transaction and your raw data. Thus it must be encrypted before it ever reaches the blockchain.

Should I be encrypting data in a CloudSQL database?

Google CloudSQL documentation states that the data is encrypted in transit and at rest.
I'm using pgcrypto in a Django app to encrypt sensitive information. However I'm wondering if there's any point in doing this since it's already encrypted at rest. The only thing I can imagine is an event where the Google App Engine server with the deployed code gets compromised and the password to the database is somehow leaked - the hackers would eventually have access to unencrypted data as they 'read' it in. But then even with pgcrypto, in the event the GAE server is compromised, they'd still be able to run code to fetch unencrypted data.
Am I overthinking this? The goal is to provide total piece of mind to the end-user with as many 'hurdles' introduced as possible to ensure their data stays completely secure. I have a feeling I don't really need pgcrypto, but looking for an educated reply.
The rather educated answer is: Yes.
Underlying encryption offered by CloudSQL is like FileVault offered by OS X - your stuff truly is encrypted, but if you're logged in, everything is world-readable to you.
The main worry is that you, or someone who is able to compromise your server, is able to read data in plain-text. Data needs to to be encrypted, and I've personally gone beyond the default AES 128-bit offered by most databases and switched to AES 256-bit with initialisation vector (a different one for each encrypted content). This will ensure that the data is encrypted, inaccessible and unreadable by even yourself. Yes, your code is eventually able to decrypt but storing and protecting the decryption keys is a different topic altogether.

Should I bother with web server database and file encryption?

I'm launching a Python Django web app on Heroku, using the default PostgreSQL database. I'll also be using a AWS S3 to store some files. The client I'm creating the site for is rightly concerned with security and asks is we can encrypt the database and the files stored in S3.
Am I correct in saying the only benefit that encryption will have, is it will protect our data in the unlikely case somebody breaks into one of Amazon's datacenters and happens to steal a hard drive on which our data is located?
I've come to the following conclusions:
Unless somebody gets hold of my AWS credentials or Heroko login details, the data is as safe as it can be.
Also, even if the data is encrypted and they get hold of my credentials/login details, they will still be able to read the data.
The key in keeping the site secure is just making sure nobody gets hold of my credentials/login details.
It is therefore not necessary to encrypt the database and files unless we believe there is a strong possibility of somebody breaking into an AWS datacenter.
Are my statements above correct?

How can I uniquely identify a desktop application making a request to my API?

I'm fleshing out an idea for a web service that will only allow requests from desktop applications (and desktop applications only) that have been registered with it. I can't really use a "secret key" for authentication because it would be really easy to discover and the applications that use the API would be deployed to many different machines that aren't controlled by the account holder.
How can I uniquely identify an application in a cross-platform way that doesn't make it incredibly easy for anyone to impersonate it?
You can't. As long as you put information in an uncontrolled place, you have to assume that information will be disseminated. Encryption doesn't really apply, because the only encryption-based approaches involve keeping a key on the client side.
The only real solution is to put the value of the service in the service itself, and make the desktop client be a low-value way to access that service. MMORPGs do this: you can download the games for free, but you need to sign up to play. The value is in the service, and the ability to connect to the service is controlled by the service (it authenticates players when they first connect).
Or, you just make it too much of a pain to break the security. For example, by putting a credential check at the start and end of every single method. And, because eventually someone will create a binary that patches out all of those checks, loading pieces of the application from the server. With credentials and timestamp checks in place, and using a different memory layout for each download.
You comment proposes a much simpler scenario. Companies have a much stronger incentive to protect access to the service, and there will be legal agreements in effect regarding your liability if they fail to protect access.
The simplest approach is what Amazon does: provide a secret key, and require all clients to encrypt with that secret key. Yes, rogue employees within those companies can walk away with the secret. So you give the company the option (or maybe require them) to change the key on a regular basis. Perhaps daily.
You can enhance that with an IP check on all accesses: each customer will provide you with a set of valid IP addresses. If someone walks out with the desktop software, they still can't use it.
Or, you can require that your service be proxied by the company. This is particularly useful if the service is only accessed from inside the corporate firewall.
Encrypt it (the secret key), hard-code it, and then obfuscate the program. Use HTTPS for the web-service, so that it is not caught by network sniffers.
Generate the key using hardware speciffic IDs - processor ID, MAC Address, etc. Think of a deterministic GUID.
You can then encrypt it and send it over the wire.