zero knowledge encryption with keycloak - encryption

Here is my structure:
A database where I store sensitive information.
A frontend app where the user interacts.
A backend to receive interactions and manage data accordingly
Keycloak for auth
I have been reading a little bit, and I have concluded that storing sensitive information in the database could pose security risks.
A solution could be to use zero knowledge encryption:
user authenticates with password
frontend uses the password to encrypt data sent to the backend
backend stores encrypted data
The problem is that I have no access to the password since Keycloak stores it internally.
Do you guys know if there is a way of implementing a solution like this? or a better alternative? I am new to cryptography.

Related

Where to start encrypting a user password?

I have an issue when it comes to encrypting user passwords. I have a authorization services with which one can create a user account. Given is an email and a password. As for now I encrypt the user password in the server before persisting it in the database.
However I feel that is somewhat wrong because the password is in plaintext when coming in through a https request. So I actually could log the real passwords of users.
Isn't that a dangerous way to handle user passwords? I think it would be better to encrypt user passwords in the client side code (javascript) before submitting a form (either registration or login). So the password will arrive encrypted already.
Am I right with my concerns?
I encrypt the user password in the server before persisting it in the database.
Please don't. Use slow salted hash if possible (BCrypt, SCrypt, Argon2,..)
If you really cannot use the mentioned functions, than a database native hashing functionality is better than encryption.
https://practice-code.github.io/architecture/how-to-store-passwords-in-a-secure-way/
the password is in plaintext when coming in through a https request
Nope, the https encrypts traffic between the client (browser) and the server.
Yes you can see the password in the browser side before encryption (but the user entered the password, so it looks ok to access its own data) and the server needs to validate the password anyway.
Isn't that a dangerous way to handle user passwords?
Indeed. So maybe it's a good idea to offload the user authentication to already proven services (AWS Cognito, IBM AppID, Azure AD,..) or to social accounts (Google, FB,..)
I think it would be better to encrypt user passwords in the client side code
As already commented, that is not helping at all. Then the encrypted value becomes the password
Nothing is in clear text when using HTTPS, data is encrypted that is the main point of using server certificate !
As an alternative approach usually one stores the password hash in db instead of the password text, so eventually your code uses hash algorithm to generate the password hash and compare it versus one stored in DB, by that even if someone was able to access the database records ,that one is unable to figure out what is the password because all he gets is the hash value
Using Hash in C#

How do I migrate to hashed Firebase passwords?

I have an existing client, which calls a server, which in turn calls
https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword
With that, client POSTs to the server (and server, to Firebase) an unhashed password over HTTPS.
I would like to salt/hash the password on the client. I am at liberty to use the same algorithm Firebase uses. But I don't see a method for sending a hashed password to Firebase. And I have existing users who, of course, can't lose access with this migration.
To sign in to Firebase Authentication's email/password provider, you have to send the password in cleartext over a secure connection. There is no way to change this.
This is not a security risk to send the password in cleartext, as the secure connection is end-to-end encrypted, so the only two sides who can see the data can already access it anyway. If somebody can intercept the data and decrypt it, it means they have access to the certificate of your secure connection, which is a much broader security risk.
Of you want to sign in with a password in a different form, the only way to do that is by implementing your own custom provider on top of Firebase Authentication.

Can I encrypt password on both frontend and backend?

I'm making an application that needs logging in.
I used node.js as API.
I understand I have to encrypt the password on backend in case the database is stolen.
But if for some reason HTTPS failed or some developer on our side had malicious intention he/she could easily steal the raw password if it wasn't encrypted on the frontend as well.
So my question is is there a problem if I use Argon2 on backend and BCrypt on frontend together?
(Also I assumed that Argon2 is faster so if the attacker wants to brute force he has to use the slow one as well on his side instead of my api heavylifting his/hers shannigans)
I know there are some simillar questions, but they ask if i should use one OR the other and the answer is backend and HTTPS.
I WILL use HTTPS and backend encryption. But I ask if it's possible (or a good idea) to use encryption on the frontend as well.
Argon2 and BCrypt are not encryption algorithms. They're password stretchers (formally "PBKDFs" or "Password-based Key Derivation Functions"). It doesn't make sense to use both, however.
The design you're looking for is this:
Apply a password stretcher on the front-end so that the raw password is never sent to the server.
On the backend, apply a fast hash (SHA-256) so that the hashed password is not stored in the database.
The first part protects the user. Their password never leaves their machine. The second part protects your database. Even if it's stolen, there's no way for an attacker to use the hashes stored there to log into your system.

Web API BasicHttpAuth with hashed password

So I have a web Api that authenticates users by username and password. The clients talking to the API will android phones that have an internal app on it to get / send some data from / too the api.
I have hashed passwords in the database with a salt. The connection between the client and the API will be SSL.
Now on the website (MVC) I log users in by generating a new hash and matching this against the hash in the database.
The some of the android devices will have a config file that locks the app to a specific user. Now I rather not store the password in plain text on the device and would like to encrypt the password.
The question now is what would be the best practise here on comparing the hashed password. I dont think its save to just send the plain password to the API or is it?
It's safe, because you're using SSL.
Basic authentication isn't acceptable for plain-text requests, but since HTTPS encrypts everything, it shouldn't be an issue.
Storing the password is a completely separate concern, as you've noted, and that should be encrypted as well, which it sounds like you'll have Android do for you. The only consideration is that you will have to do a reversible encryption to be able to send up the password itself to your API.
Basically:
(client-side) User enters creds
(client-side) Encrypt creds, store in configuration
(client-side) Read from config, decrypt creds
(client-side) File HTTPS request to API with Basic authentication type, using decrypted creds
(server-side) Hash (one-way encrypt, basically) the password, compare against database
That sounds like exactly what you've got, and I see no problem with it.
That all said, just for what it's worth, I'd be tempted to implement an OAuth 2.0 server for this particular use-case, so you don't have to think about persisting the password at all. That's a pretty big undertaking (sort of--it doesn't take too long with those instructions), and you should evaluate it on a case-by-case basis. But any time I have to worry about API authentication, I generally wind up either going with that, or wishing I had.
I would consider using something like JWT (JSON Web Token, http://jwt.io). You can have a client authenticate against your API, and if they provide the right credentials you can issue a token to them, which they can persist on local storage. They would then provide this token in the header of any API requests that require authentication. You can use OWIN middleware to intercept requests, check/validate the token and let the requests through to your controllers if you consider the token to be valid.

Is basic access authentication secure?

Using Apache, it is quite simple to set up a page that uses basic access authentication to prompt a user for a name/password and use those credentials in some way to grant access to that user.
Is this secure, assuming the connection between the client and server is secure?
The worry about basic auth is that the credentials are sent as cleartext and are vulnerable to packet sniffing, if that connection is secured using TLS/SSL then it is as secure as other methods that use encryption.
This is an old thread, and I do not believe the highest voted/chosen answer is correct.
As noted by #Nateowami, the security stack exchange thread outlines a number of issues with basic authentication.
I'd like to point out another one: if you are doing your password verification correctly, then basic authentication makes your server more vulnerable to denial of service. Why? In the old days, it was common belief that salted hash was sufficient for password verification. That is no longer the case. Nowadays, we say that you need to have slow functions to prevent brute forcing passwords in the event that the database becomes exposed (which happens all too often). If you are using basic auth, then you are forcing your server to do these slow computations on every API call, which adds a heavy burden to your server. You are making it more vulnerable to DoS simply by using this dated authentication mechanism.
More generally, passwords are higher value than sessions: compromise of a user password allows hijacking the user's account indefinitely, not to mention the possibility of hijacking other systems that the user accesses due to password reuse; whereas a a user session is time-limited and confined to a single system. Therefore, as a matter of defense in depth, high value data like passwords should not be used repeatedly if not necessary. Basic authentication is a dated technology and should be deprecated.
The reason why most sites prefer OAuth over Basic Auth is that Basic Auth requires users to enter their password in a 3rd party app. This 3rd party app has to store the password in cleartext. The only way to revoke access is for the user to change their password. This, however, would revoke access for all 3rd party apps. So you can see what's the problem here.
On the other hand, OAuth requires a web frame. A user enters their login information at the login page of this particular site itself. The site then generates an access token which the app can use to authenticate itself in the future. Pros:
an access token can be revoked
the 3rd-party app can not see the user's password
an access token can be granted particular permissions (whereas basic auth treats every consumer equally).
if a 3rd-party app turns out to be insecure, the service provider can decide to revoke all access tokens generated for that particular app.
Basic auth over http in an environment that can be sniffed is like no auth, because the password can be easily reversed and then re-used. In response to the snarky comment above about credit cards over ssl being "a bit" more secure, the problem is that basic authentication is used over and over again over the same channel. If you compromise the password once, you compromise the security of every transaction over that channel, not just a single data attribute.
If you knew that you would be passing the same credit card number over a web session over and over, i'd hope that you'd come up with some other control besides just relying on SSL, because chances are that a credit card number used that frequently will be compromised... eventually.
If you are generating passwords with htpasswd consider switching to htdigest.
Digest authentication is secure even over unencrypted connections and its just as easy to set up. Sure, basic authentication is ok when you are going over ssl, but why take the chance when you could just as easily use digest authentication?
As the name itself implies, 'Basic Authentication' is just basic security mechanism. Don't rely on it to provide you with worry free security.
Using SSL on top of it does makes it bit more secure but there are better mechanisms.

Resources