Logging in to a database using encrypted keys - encryption

How to log into a db using encrypted keys ? If I use the encrypted string for the password to a particular database , can I login to the database ?If no then how to program the automatic decryption ?

Related

How to save encrypted String in Firebase with Dart Flutter and decrypt in app?

I am developing an application and I have a connection key for this application. I want to keep this key encrypted in Firebase and use the decrypted version in the app. So I'll keep it encrypted in Firebase and decrypt it and use it in the app.
I am using Firestore.
You can think of it as a password control system. It is kept encrypted in Firebase, the encrypted password is decrypted in the login part and the password accuracy is checked.
Thanks in advance for the help.
Usually passwords are stored as hashed strings, not like encrypted data.
If you want to encrypt before uploading to database and decrypt in the app after fetching it, you can use any of the symmetric encryption algorithms
If you want to store passwords as hashed strings, you can hash the password with sha-256 before uploading to the database and when you need to check in the app if the given password is true at login, you can hash with the same hashing algorithm and compare with the hashed strings in the database.

Flutter - Key storage for end-to-end encryption across multiple devices

I am writing a flutter application where the user can essentially create notes. I have written code to create a private key for the user, which is later used to encrypt their data. The encrypted data is stored in Firebase Firestore. When their data is retrieved it is decrypted using their key.
I've looked at using Flutter Secure Storage, which works great, except that the secret key is only available on that device. If the user logs in on a new device, they will not be able to decrypt their notes.
My question is:
How/where can I store the user's secret key for decrypting their data so that only they have access to it, regardless of what device they log in with? What is best practice around this kind of solution?
final AesGcm algorithm = AesGcm.with256bits();
final SecretKey secretKey = await algorithm.newSecretKey();
// TODO: Write secretKey to storage that only the user can access with their account.
As explained by David in the Virgil Security talk at GDG, this problem is overcome by utilizing the user's password to derive a key (which David refers to as a brain key) which is then used to encrypt the user's private key. So, when a user signs up, a private key is created for them, which is then encrypted using the brain key. This encrypted password key is stored in the cloud.
Thus, when the user logs in from a new device, they type in their password and get the brain key from the password which is then used to decrypt their private key and is consequently saved to the user's device. Now, you might be wondering what happens if the user changes their password. In order to change one's password, the old password is required which is then used to create a new brain key and store the private key in an encrypted format.

Hashed password to mail server to login

I stored the email's password in the database by using Bcrypt and since hash function is only one-way it's not possible to retrieve the plain-password to send to the mail server to log in. So what are the best options to store the password in the database so that I can retrieve it?

How to encrypt user data in Firebase

I am using the email/password sign in method for Firebase. I would like to encrypt the data users save into the realtime database before sending it to the database. Firebase already handle the user password, but can I somehow use it to encrypt data which can't be decrypted by me only the client? It would be nice if I could achieve it with the client sdk.
So my flow would be something like this:
User sign in with it's credentials (which is handled by firebase itself)
User encrypt some data with some unique key, which can be generated only from the credentials or from some data available only for the user, but not me. (this key needs to be persistent between sessions, or after the user changed his password.)
Data is saved into the database (I cant read it since its encrypted with the user credentials)
User log in on a different device (the decryption key can be generated right away and data can be decrypted.)
You can easily do that the following way:
After user A logs in a random public private key pair is generated on his phone. eg.: use Ecc Curve25519
The private key from A is stored securely on his phone
The public key from A is stored in firebase and is accessible to anybody that chats with A.
If X sends a message to A he fetches the public key from A from firebase encrypts the message for A locally and stores the encrypted message on firebase in the inbox from A
A downloads the encrypted message from firebase and decrypts it with his private key stored on his phone
(vice versa for A to X)
If A want's to move to another phone or wants to use multiple phones you can do this that way:
Ask A to define a strong password to encrypt his locally stored private key. (or create a random passphrase and use QR codes for key exchange)
Encrypt the private key locally (eg.: use AES256) on his phone with the password from step 1 and upload it to firebase. (optional sign it with his private key)
Download the encrypted private key from the second device from A
Ask for the passphrase on the second device from A and store the private key securely (optional check the signature with the public key from A)
Delete the encrypted private key from firebase if no backup is wanted

Server-side public key encryption with browser-side decryption

My application requires certain fields to be encrypted when stored at rest, and allow the user to decrypt them locally in the browser by entering a passphrase. However, these encrypted fields are not entered into the database by the authenticated user himself, but submissions from other people who are supplying the user with private information.
If I stored the passphrase in the database to encrypt new submissions, then anyone who got access to the database would be able to easily decrypt the encrypted information. So, I believe I need to store a public key in the database, encrypt incoming information with the public key, and then serve that encrypted info to the user and let him decrypt it with his passphrase in his browser. (Thus, serverside, we can never decrypt anything.)
I've looked into libraries like ursa, but the problem is that the user would have to save his private key. (Correct?) Is there any way that I can do this with a relatively short passphrase instead of a long private key?
You can use something like JSBN to generate a public-private key pair on the client and use CryptoJS in password encryption mode to encrypt the private key with AES. The encrypted private key and the plaintext public key are then posted to the server and added into the database.
The next time the user gets information encrypted with his/her public key, you send the encrypted information and the encrypted private key to the client/browser. The user can enter the passphrase again to decrypt the private key and then in a second phase decrypt the payload.
Note that this is not absolutely secure because unencrypted traffic (e.g. no TLS) will enable an attacker to extend the html/js to include a data stealing script. Furthermore, the developers of your system can also add such a script whenever they want regardless of TLS or not.

Resources