If I want to encrypt data on a server, and send it to a client program which I have implemented and sent to the customer, is there anyway that I can store the decryption key and algorithm in the client program, without risking that reverse engineering my client program will enable the user to decrypt all the data I send.
That is, I want my client program to control what it decrypts and what not.
Thanks
Jeeji
You can hard-code the algorithm with no risk. The security must be based in the secrecy of the key, not of the algorithm.
To secretly store the decryption key, you can use a keystore.
I don't know which language you are using, but Java includes its own keystore, and for C you get a keystore through NSS. To open these keystores you will need a password that the user can type in when the client application starts up.
If your client runs on linux and gnome, then you could also use Gnome's keyring, in which case the user will not need to type the password to open the keyring (the log-in password is also used to open the keyring).
Related
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#
I am developing an application that'll decrypt encrypted files when a user successfully logs in. From what I understand, OpenSSL does not have a built-in function for this. So what I plan to do is zip up a folder and encrypt the zip file when I want to encrypt the directory and the reverse when I want to decrypt it. I will use the aes-256-cbc algorithm. The problem is, a user could change their password in my application, so the new password will generate different key and IV pair meaning that I can't decrypt the folder. Does anyone have any suggestions? Login credentials are verified on the server and encrypted zip files are located on the computer running the client application.
The problem is, a user could change their password in my application, so the new password will generate different key and IV pair meaning that I can't decrypt the folder.
The practice is not to use the user credentials to encrypt the data. If the user forgets his credentials, the user is done for.
Login credentials are verified on the server and encrypted zip files are located on the computer
That's actually giving you an option. If you don't want to store the encryption key on the client side, the server could send the key back as a part of the response and the client application could use it to decrypt or encrypt the data.
I'm implementing 2FA on my app with phone number verification. As SMS are not free, I really need to ensure that a request to my server comes from my app and not from any third party http request launcher.
For this purpose, I thought about encrypting the http request with a key provided by my server within my app, and send that encrypted request. As my app is a binary (this is not applicable for web of course), I was thinking it would be difficult to see the encrypting method. The process would be the following :
my app asks my server a key
my server generates, stores and returns a random key
app encrypt the whole actual request with a "secret" method, depending on that key (secret = in binary so hardly readable)
app send to server the encrypted request + the key
The server sees if the key exists, and tries to decrypt the request. If it manages to decrypt, it proceed the request, and then remove the key from its storage so no one can use it anymore.
I don't see any to compromise this system, except if someone manage to read from apple/android binary app the encrypting system the app uses.
Do you think this can be a good process ? Do you see any way to compromise this system ? Is reading from a binary file is really difficult ?
I will start with the flaws in your design, from an android perspective, even if you have enabled pro-guard for your app, we can still decompile the app and trace back the api calls
If your server is not using HTTPS - its easy to trace the calls going
back to the backend server by routing through a proxy server like
charles proxy, and analysing the response, even if you are using
https its possible to install ssl certificates to trust the proxy and
get the response. Also by analyzing the outbound requests its
possible to extract the signed key from the app
Its easy to decompile an apk package and opening it in IDEs and
searching for the backend server url by inputting 'api' or
'http','https' keywords on the ide project search window
If you are storing the secrets in shared preferences or storage, it
can be read from the device ,if the attacker has root access to file
system.
then remove the key from its storage so no one can use it anymore.
For the above scenario, i will run the app and once it stores the key , i can change the permission to read only , so even if the app tries to remove it , it wont be deleted
You can use SSL-Pinning, and putting the keys in compiled libraries making it difficult for the attacker to decrypt the key, also you need to make sure that you don't create any other loop holes
You may also share the common key between app and server through alternate channel , like an email . Where the user once he registers for the App gets and Email with a QR code which once scanned will give the server key. The security of this approach is tied to the secure access of the email by authorized user.
You may them follow the standard approach of sending the encrypted request to server to verify the phone number , once done you may delete the data form your app storage.
I'm looking for USB token solution for asymmetrical decryption purpose. The server has encrypted sensitive data with periodically rotating data encryption key (DEK), which is stored alongside with the encrypted data, encrypted itself with pre-distributed public key of the USB token (KEK).
The user (web browser client) logins to the single page application with username and password. User then inserts the USB token, which will trigger the following sequence:
Retrieve the encrypted DEK's from the server
Decrypt the DEK's with USB token private key
Retrieve the data from the server with the DEK's
I have looked into solutions like Yubikey, but it seems to be more focused on the user authentication than cipher services. What is the correct product to implement hardware based cipher in portable format? Expensive HSM is out of question, as multiple users should posses an instance of the portable token. Also, each instance should contain the same private key.
Nice idea, however you are having a few issues
Decrypt the DEK's with USB token private key
Currently no browser supports using decrypting by pkcs#11 (smart card or usb token keystore protocol) directly.
The browsers can use a stored keypair to authenticate and that's it. (if I missed something, please correct me).
Though you could use some local utility(non-web) to decrypt using a smartcard (gpg, openssl,...)
Also, each instance should contain the same private key.
Most of the serious smart cards allow generating a new private key, but you not importing own key material (at least the ones I had). So it is difficult to create multiple smart cards with the same keypair
What you could do is encrypt the DEK for a set of public keys
I want to build an app where users upload files. But the owners of the server should never be able to have access to any data from the files, only encrypted content.
If I had to implement it myself using Java, I would do something like:
symmetric encryption for the files using a random key per file (or per user because I don't need per file access control). The random key is then asymmetrically encrypted (one time for each user needing access to the file) and stored along the file on the server
Users have a password encrypting their randomly generated on account creation private key stored on the server along with the public key.
The user password hash (not the password itself) is also used as an authentication password to avoid having multiple passwords but also to avoid sending the user password to the server (the server then normally computes and compares the salted hash of this hash of the password)
How can I implement a custom app like this (using libraries?, running additional servers with http APIs?, something else?) ?
I found https://www.minio.io/features.html, an http server with s3 compatible rest APIs which has "Both server side and client side encryption are supported" but couldn't find enough documentation on the client side encryption.