How can user access any of his messages after RSA encryption? - algorithm

I am planning to build a site to exchange messages securely using the Rsa algorithm and the end-to-end encryption. Question here: As we know from RSA encryption, if User1 wants to send a message to User2. User 1 requests User2's public key and encrypts the message.
User 2 can learn the message’s content by decrypting it using his private key.
Well ... how will the first user be able to access his message after it is encrypted?
It was stored in the database in an encrypted form.
There is an option to solve the problem but I think it is impractical.
When User1 creates a message to send to User2, he encrypts it with his public key and keeps it in the database
Then he encrypts the original message with User 2's public key and also saves it in the database.
Do you have any alternative solutions or suggestions?
thnx

The messages between User 1 and User 2 can be encrypted using a symmetric cipher with a key which they both share and only use for messages to each other. The key itself can be stored encrypted with User 1's public key, and separately stored encrypted with User 2's public key, so that each user is able to access the symmetric key to decrypt messages they sent as well as messages they received.

Related

Offline check a token's validity against user alteration

I have a question about protecting data against an untrusted end-user in the following scenario:
Basic feature to implement:
User logs into desktop app using username and password in order to have access to a subscription based software
The server respond with an encrypted token having a validity (30 days for example) and a Hardware Identifier specific for that one machine for which the user is now entitled. The server also responds with a public key with which the token above can be decrypted/checked
Every time the user launch the desktop app, if we are in an offline scenario we check the validity of the token by decrypting it with the public key, and then we can check if it is still within the validity period, and if it is on the correct Hardware as well (i.e. if the user did not just copy the encrypted files on a different machine and try to use the same account on more computers simultaneously)
Problem:
The scenario above has no protection against an untrusted user.
Example of possible attack:
The user decrypts the token using the public key
He now edits the token and sets a new Hardware Identifier, for the new machine he wants to copy the tokens
He edits the expiring date to 31.12.2099 for example
He generates his own private-public pair of keys
He encrypt the token again with his own private key
Now he can transport the encrypted token together with his own public key on the new machine, and as soon as he launches the desktop app in an offline scenario, the app has no way to tell that the token has been altered. It checks the authenticity of the token, but it can't check that the public key has been corrupted as well.
Every asymmetric encryption approach assumes that the end-user is trustable. For example when signing an app with a certificate, we assume that the user has no intention in attacking the offline trusted root certificates.
A solution I avoid would be to encrypt the private key or the public key within the code, but:
That is very very unsafe
That is not flexible in case you want to update the keys
It can be reversed engineered
After studying cryptography for a while I never realized that this scenario is so unsafe. Now I am wondering how a lot of already existing apps work in this scenario without exposing themselves to this so easy attack?
Thank you!

How do I transfer an account between parties on the NEAR platform?

From the docs:
Accounts can be atomically and securely transferred between parties as a native transaction on the network.
I know the currently support Actions on the network are:
CreateAccount
DeployContract
FunctionCall
Transfer
Stake
AddKey
DeleteKey
DeleteAccount
source: https://nomicon.io/Runtime/Actions.html
I know from NEAR Shell that the DeleteAccount action takes an account to be deleted (the "sender") and a beneficiary account (the "receiver").
Is this what is meant by "atomically and securely transferred between parties"? Applying the DeleteAccount action?
Or am I missing something?
The idea behind the secure transfer is the ability to replace access keys.
Let's say you have an account alice and you want to transfer this account to me.
I give you a public key (without revealing the private key).
You create a transaction and sign it with your current private key. The transaction has 2 actions: remove your key, add my public key.
Now alice account has my public key, so only I have access to it. And you don't have access to alice anymore because it doesn't have your key, and you don't know my private key.

Is it secure mechanism of sharing data?

I need to share a file with some users. Using the way described below. Is it secure to share keys?
I have a data file.
I will encrypt a file, using any algorithm(GPG, OpenSSL).
Before encrypt I create keys private and public.
Then I upload a file to public storage.
If someone will find a file, and download it, he couldn't read encrypted file.
If I share my keys (private or public key?) with someone whom I want to share, he could decrypt use the same algorithm with my key.
Is it secure to share a key to decrypt a file?
If you wanted to share an encrypted file with someone, that intended recipient would give you their public key. You would encrypt it with the recipient's public key and only the recipient would be able to decrypt it with their private key.
Generally, no, it is not secure to share a key.
Other things to consider:
Public/Private keys can only encrypt a small amount of data by themselves. Generally they are used to encrypt symmetric keys that are used to encrypt/decrypt the payload. Using GPG etc would likely generate a "file" for you that has the symmetric key encrypted with the recipient's public key as well as the symmetrically encrypted payload. The recipient decrypts with their private key.
When you get your intended recipient's public key, how can you be sure the public key came from your recipient? Read up on the concept of man-in-the-middle for some things to consider.

how to encrypt data in database and reuse it to authenticate users

I'm developping an application with Spring MVC, and I want to add the security aspect to my authentication.
In my application I have the login and the password are registred in the database and any one who has access to it can see the login and the password clearly.
I want to have data encrypted in the database so that I will be sure that no one can use or divulgue them .
I've searched in the net but I found that there are some algorithms which may encrypt data such as md5 ,but the problem it's irreversible.
Could some body help me ?
I agree with Danny H, but wanted to address the other half of your question too: protecting the login (usually an email address). Most people ignore the need to protect it, but for website that want to maintain secrecy of their customers (not just Ashley Madison but also medical websites), then you'd want to add a layer of protection for the other data.
First, a reference on protecting the password: Secure Salted Password Hashing. Use either bcrypt, scrypt, PBKDF2, or argon2.
Now what about protecting the login? You can actually do a similar thing for protecting it, but you will need a fixed salt for it (for passwords, the salt must not be fixed!). Let's assume bcrypt is used for my example below.
Consider how the user would login: User enters his login id and password. System applies bcrypt to login id with fixed salt to look up user in database. From that, system gets the user's password salt, and system computes bcrypt on user provided password with salt to see if it matches hashed password in database. If so, user is granted access. Therefore, system granted access without storing the user’s login id in plaintext form in the database.
What about user forgetting password? No problem if the login id is the email address: the user enters login (email address) on forgot password page, system applies bcrypt with fixed salt on user entered email address to see if the user exists in database, and assuming yes, then emails the user a secret link for password reset. Within the database, we have to associate that secret link to this user to make sure he only resets his own password (not somebody else’s!).
What if the database is exposed? Anybody could determine if a specific user is in the database by computing bcrypt on that user’s email address and looking for a match in the database, but nobody is going to be able to reverse the entire collection of email addresses, which is a big improvement over the present situation.
I discussed this idea in a blog of mine more than 2 months ago, see: https://littlemaninmyhead.wordpress.com/2015/09/08/a-retrospective-on-ashely-madison-and-the-value-of-threat-modeling/
Why is it a problem that the encryption of passwords is irreversible?
When the user creates an account, salt and hash their password before saving. I prefer using bcrypt.
When the user logs in, you can use bcrypt's checkpw to compare the users credentials to the hashed ones saved in the db. Having them irreversible(undecryptable) ensures that if someone gains access to your db, they don't get all of your users passwords as well
I haven't used BCrypt with java before but I just glanced over this tutorial and it seemed like it may be a good starting place for you
Edit : Just realized he was using jBCrypt but the differences in the two should be very minimal
Edit2 : Here is a pretty good article on cracking passwords that are found in the database and a reason I recommend bcrypt and why you should use one-way encryption
MD5 is a hash function which is not reversible - it is not an encryption function. Hashes give the same output for a given input every time, that's why they work. Hashing would work in the scenario you described because the users who could see the hashes wouldn't know the original password - that said, it still sounds like a bad idea.
Ideally you would hash the passwords then encrypt the hash and other users wouldn't be able to see these values encrypted or not. That would be my suggestion, but if you choose only to encrypt the passwords RSA encryption would work just fine.

Public Key signing/verification

I'm developing an application to manage file and email encryption using (primarily) PKI. I have a Public Keyring with a list of contacts and their Public Keys.
Referring back to the olden days when I used PGP, I recall a requirement to sign public keys with your Private Key.
Is this a necessity on PKI and if so, what does this signing achieve? Is it bad practice to simply hold a list/database of people's names (and email) and their Public Key? Surely if their public key is - in any way - tampered with the encryption would fail and as you choose who you're sending or sharing the encrypted data with, even if a 'successful tamper' went unnoticed, the encrypted data wouldn't end up in the wrong hands anyway?
The whole thing about signing a public key with a private key is useful when you have a dedicated key-pair that you use only for signing, and then other key-pairs that you use for encrypting. This dedicated key-pair is your "trusted" key-pair that is somehow known to be legitimately attached to you (often by having it signed by a certificate authority or by having many trusted people sign that they have verified it's connection to you.)
You use this "trusted" private key to sign your not-quite-as-trusted public key. This way, people can un-sign/decrypt your new public-key with your trusted public-key. This is only mathematically possible if it was signed by your trusted private-key.
This process helps people to be sure that this new public-key actually belongs to you.

Resources