I am building an app that uses encryption.
The issue is that I'm not familiar with the best approach to store a private key.
Lets begin with an example:
Messaging apps that have end-to-end encryption, so the sender uses the public key of the receiver to encrypt data and the receiver uses its private key to decrypt it. Right?
But what is the approach to storing this private key?
I mean, if I store this key in a database it is as good as nothing, if my database get hacked then all the private keys are exposed.
Also, if I store the key on the device, there is also the possibility of someone finding the key and owning it.
My question is, what do I do with the private key?
What is the current approach to this problem?
For example, how does telegram stores its user keys securely?
My question is, what do I do with the private key?
You can encrypt the priv key using the Android Keystore System MasterKey, which may request authentication (biometric, device pattern, pin) upon decryption.
KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC;
String mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec);
iOS has similar mechanism, but you have to search it yourself
Related
When using the transit secret engine of HashiCorp Vault, the vault has to be called to encrypt data.
Now, I have the situation that I want to encrypt data in an insecure location, where I can't store the credentials for the encryption service. For those situations, asymmetric encryption is the perfect answer. I can use the public key to encrypt the data in the insecure location without calling the vault. But later, I can call the vault from a secure location to decrypt the same data.
From what I see, Vault only supports rsa-2048 and rsa-4096 which can't be used for large data. All other ciphers are symmetric.
Do I misunderstand something here or does HashiCorp only support asymmetric encryption for small data?
I am implementing a secured system( using .Net Core 2.0 ) where there is a requirement of key pair ( public and private ) generation and transmit the public key to a recipient. At the moment I do generate the key pair( using the .Net Core Crypto library) and persist the private key in the DB. I need to host this in an AWS EC2 instance.
I know this is a bad practice(storing a private key in a DB) and I need to generate these keys in a secure vault ( AWS ? ) and persist the private key in the vault itself. The application needs to retrieve the corresponding private key when there is a requirement for decryption.
I went through many AWS docs but could not find a clear answer which caters my requirement. It would be great if someone can provide me with some clear instructions on how to achieve this.
You are right in pointing out that self-storage of secrets in DB is a bad practice. Depending on the extent of functionality you wish to offer via your application, you could use one of the below AWS offerings:
AWS Key Management Service
In case you need the key generation as well as the key storage to occur in AWS, Key Management Service(KMS) is the closest match. Here is a link to the AWS KMS home page, along with documentation. Bear in mind that choosing this option will restrict the exact mechanism of key generation to whatever AWS offers out of the box. Also, the standard use case for KMS doesn't include generating keys in high volumes which could be a possibility for your application.
AWS Parameter Store
If you decide to include the key generation logic within your application, and leave the storing part to AWS then Parameter Store is the offering for you. In order to add a new key to a parameter store, you can do the following:
aws ssm put-parameter --name Generated_Public_Key --value "Generated_Private_Key" --type SecureString
When a client of your application requires a previously created private key by providing the public key, you can use the following:
aws ssm get-parameter --name User_Provided_Public_Key --with-decryption
Just a side note in case you decide to look outside of AWS, Microsoft Azure has an offering similar to Parameter Store called Azure Key Vault.
You can try t-vault
https://github.com/tmobile/t-vault
Its an open source tool built on top of hashicorp vault. It simplifies the secret management for applications.
Here is a quick demo
Is there any recommended way to encrypt data in Firestore? Even though Firestore, by default, encrypts data before it writes to the disk, admins still can read data in the console. I am looking to make the data readable only by users who are allowed decrypt it. So it will be unreadable in the console.
One way I think it may be possible is to use cloud functions but I can't find how to modify the data before it gets saved to the disk (beforeWrite hook).
The only way to control all access to all data in Firestore (or Realtime Database for that matter) is to perform encryption on the raw data itself before it's even passed to the client APIs or SDKs that perform the write.
It's not possible to hook writes before they actually commit to storage with Cloud Functions. A function will only receive an event after the data is successfully written.
Also, bear in mind that if you encrypt data before it reaches the API, you will be unable to search and sort using that data, because it will no longer represent the original data in any way. All you would be able to do is access a document/location by its unique key (assuming that key is also not encrypted, or the encrypted id is (cryptographically) shared between both parties through another secure channel.
You'll need to encrypt data on the client devices before you write them into Firestore. When the other device reads up the data, decrypt it.
Key management is what you'll need to spend some time with to implement: Users on both devices need to have private keys locally and public keys accessible to the other users to encrypt messages with. Then you'll need to create a data encryption key to encrypt/decrypt messages in the chat room. This data encryption key, you'll encrypt with the participating users' public keys. And all keys, store in Firebase, encrypted.
Check out these 2 sample apps for a Firestore chat app example:
iOS: https://github.com/VirgilSecurity/demo-firebase-ios
Android: https://github.com/VirgilSecurity/demo-firebase-android
David
As far as I know, Firebase sends data over an HTTPS connection, so that the data is already being encrypted. Although Firebase provides security rules to protect my data structure, I can still be able to see the string messages in the database.
I'm just curious whether it is a good idea to encrypt messages before pushing the data to Firebase or not.
Should I just move on from this topic to something else?
Thank you.
You seem to have a good grasp of how Firebase Database works: the data is encrypted in transit, and it is stored on encrypted disks on the servers. If you enable local persistence on the device, the on device data is not encrypted.
But administrators of the app can see the data in the Firebase console. If it is a requirement of your app that administrators can't read this data, then you'll need to encrypt it on the client before sending it to Firebase. A while ago a developer explained their end-to-end encrypted chat on the firebase-talk mailing list.
Hey Jeff: you're right that when you write some data into Firebase/Firestore, the data:
Is protected over the wire using HTTPS.
Then, when it lands on the Firebase REST frontend server, HTTPS terminates and the server has access to the full payload
Then the REST server routes the data to the backend/database, which also has access to the data.
When the data is written into disk, it's encrypted at-rest, but the at-rest encryption keys are also available to Google and your administrators will also see the Firestore contents
Encrypting data client side (End-to-End Encryption) prohibits all these participants/roles seeing your data.
Encrypting data on client side is fairly simple (compatibility across mobile platforms and browsers is tricky). The other tricky part is the key management to enable one user access to the decryption key without the other user sending the key over in an unsecure channel.
The way you can implement this is:
Create private & public keys for your users when you sign them up
Encrypt data on user1's device with user2's public key
Write the encrypted data into Firestore
When user2 reads up the encrypted data, her private key will be able to decrypt it.
Check out this Firebase E2EE chat sample on GitHub for iOS: https://github.com/VirgilSecurity/demo-firebase-ios and Android: https://github.com/VirgilSecurity/demo-firebase-android
HTH,
David
I have two methods that perform encryption/decryption. These methods accept three parameters ...
Plain Text (for encryption) or Cipher Text (for decryption)
Initialization Vector
Encryption Passphrase
I was planning on using Azure Key Vault to store the Encryption Passphrase but as I read through the documentation it appears as though Azure insists on performing the encryption/decryption itself.
Is there a way to just read the Encryption Passphrase from the Azure Key Vault and use it within my own encryption methods?
You could store it as a secret in the Key Vault.
Encryption/decryption is done by the Key Vault if you're using keys, not secrets.