So my Question is a combination of 3:
Does HMAC hashing also hash the message along with the Secret key send to the recipient? Or just the Secret key is hashed, leaving the message as Plaintext?
If ONLY the secret key is hashed(not hashing the message), doesn't it makes the message vulnerable to unauthorized people(attackers) if they get access to that Plaintext and easily understand it?
If both(message + secret key) are concatenated to form the hash, how HMAC is different from the 'SALTING' method?
HMAC authenticates a message. It does not encrypt it. If you want to encrypt the message, encrypt it first, and then apply an HMAC. (This is generally called the "encrypt-then-MAC" construction.)
The point of authentication is to demonstrate that a message has not been altered. The point of encryption is to prevent other parties from reading the message. Often these go together, but they don't have to.
Related
Firebase hashes user's passwords with what they call an "internally modified version of scrypt." In short, they first hash the plaintext passwords using the standard scrypt algorithm and then do rounds of AES to the hash. This is described in more detail in this thread: https://github.com/firebase/scrypt/issues/2
I've been able to reproduce Firebase's "modified version" and match the encrypted hashes exported from Firebase using Node's crypto module. The kicker is that they flip the key and data inputs so that the key is used as the message to encrypt and the hashed password is used as the key.
// Encryption
let cipher = crypto.createCipheriv('aes-256-ctr', **scryptHash**, iv)
let encrypted = cipher.update(**signerKey**, 'base64', 'base64')
encrypted += cipher.final('base64')
// This matches Firebase's exported password hashes
console.log("Firebase Custom Hash: ", encrypted)
When using cyrpto.createDecipheriv to decrypt the message, you have pass it the value of the key, but because the original key was actually the scrypt hash, we don't have this value.
The Point: Is it possible to decrypt the AES key if you have the decrypted data using the crypto module or any other library? If this is possible, it would allow us to import Firebase user's custom password hashes into other authentication systems that support standard scrypt.
I am using a local URL scheme to submit a payload to the client when a user clicks a link and have to make sure that this is only used in my specific web application.
So I am using a key pair, encrypting the payload on the server using the private key, generating a link that the protocol handler on the client can decrypt using the public key, verifying that the payload should be processed.
So is it less secure to send a private-key-encrypted payload instead of a cleartext payload plus signature (and if yes, why)?
Found out that there are other Stack Exchange sites that answer this question very well:
https://crypto.stackexchange.com/questions/2123/rsa-encryption-with-private-key-and-decryption-with-a-public-key
https://security.stackexchange.com/questions/11879/is-encrypting-data-with-a-private-key-dangerous
I should have searched a little bit longer before asking.
What you are doing is signing!
Encrypting is when a payload is being concealed with one’s public key and later decrypted with a private key. When I want to send you a secret message, I will take your public key (because I know it) and encrypt my message. This will make sure that only you can decrypt it with your private key.
Signing works vice versa. If during encryption I want to make sure that only you can decrypt me message, with signing I want to make sure that all recipients of the message can be sure in its authenticity. If you encrypt something with your private (signing), anyone with your public key can decrypt it and verify its sender.
In your case, if you just want to prove your identity (like certificates, jwt tokens, etc.), you would need to use signing methods. If you want to transfer payload securely, use encryption.
Hope this helps!
I am working on Encrypting some data using AES 128bit encryption algorithm (Symmetric Encryption Algorithm).
Problem I am facing with this is generating a Key ? As I have mutliple Users and I don't want to share the common key across the users.
Is there is any possibility to generate passphrase in such a way that it is not common to all and can be passed to AES to decrypt/Encrypt the same data?
Example:
lets assume I have a table with employee and their salary. I want to encrypt Salary Column of Employee with AES encryption.
Now when Someone authorized from HR wants to see the salary of Employee they can check, but they should have their own Key (not the common Key).
One possible solution is to create an encrypted version of the master key per user.
So you will:
Encrypt your data with a "master key"
Encrypt your "master key" with a "personal key" (one for each user)
Then, when a user provides its personal key, you use it to decrypt the stored and encrypted master key, and then use that to decrypt the data. This way the encryption for the data can be done with always the same key, and you can regulate access with the personal keys.
This assumes though the master key and encrypted data never leave the server, you will have to decrypt on the server and send unencrypted to the user (but of course use a secure line for that, against eavesdropping).
There is no way to do this if you want to send the data to the user encrypted.
Now when Someone authorized from HR wants to see the salary of Employee they can check, but they should have their own Key (not the common Key).
Using symmetric encryption - effectively there is only a single data encryption key (DEK). The DEK can be random and content specific. You cannot have multiple keys to decrypt the same encrypted content.
What is commonly done using asymmetric encryption, when someone authorizes (shares/assigns) an encrypted content to a user, the DEK is re-encrypted by the user's public key, so only an authorized user could decrypt the DEK and then content (though - the DEK is the same for all users).
when user logs in I will ask them Key
To log in the user anyway needs to provide a secret (its user password or other credentials), so - do you really need to go through all the hustle? Isn't enough to encrypt data at REST with some system-specific master key and provide the encrypted content only to an authenticated and authorized user?
So I'm developing my messanging app with encryption evolved using RSA. Currently I came up with this algorithm:
= Update for auth =
Screenshot:
In this case private keys are generated only from password, and server knows only password hash just to authorize users (unhashed password is never transmitted to server), therefore is unable to generate private keys or decrypt any old message. If server will fake a public key recipent will be unable to verify signature encrypted with sender's private key.
The problem is that server can fake a sender's private, public key and password when he signs up on a service or requests a password change and recipent will be unable to detect it. So, how can I verify that keys were not faked by the server?
So, how can I verify that keys were not faked by the server?
You cannot. So long as the clients only communicate with the server, there's no way for them to distinguish between a "real" remote user and one that's being MITMed or otherwise faked by the server.
I see a couple other serious potential issues here:
Sending an unsalted hash of a password over the wire (during the login process) is hardly better than sending the password in the clear. An attacker can sniff the hash off the wire to log in -- they don't need the actual password! -- and a non-iterated SHA256 is highly vulnerable to brute force attacks.
"private key from pass" (also in the login process) implies that you're using some sort of KDF to generate a private key from the user's password. This has multiple negative implications:
Users are generally pretty bad at choosing passwords. This implies that the private keys will also be weak.
If two users happen to use the same password, they will end up with the same private key.
Any user can attack the password (and hence the private key) of any other user that they've communicated with by running the KDF on candidate passwords.
There is no process specified for negotiating a symmetric encryption key. Using RSA to encrypt messages directly limits each message to the size of the key, and makes it vulnerable to numerous attacks if the data being encrypted is not both random and unique.
In the message exchange, the user sends the server two copies of every message -- one encrypted to the target user's private key, one encrypted to their own private key. In some situations, this may make it possible to recover the message.
I'm searching for a specific way to encrypt my data.
I want to encrypt it with my password and decrypt it with that.
Later I want to gain other people access to chosen parts of my data with their passwords.
Is there any other way than to decrypt the data everytime I add a new "reader" and encrypt it all again with a "mix" of all passwords?
And than the big question is how to decrypt without knowing the passwords of everyone?
And than I thought of another problem. How to validate that the given/login password is correct?
I thought the following might work without saving the actual password or the encryption password:
Get a password ; "Thats an amazingly bad password"
Use the hash as encryption and decryption key ; hash(salt + "Thats an amazingly bad password")
Save the hashed hash as validation for the password ; hash(hash(salt + "Thats an amazingly bad password"))
What do you think about it?
Thanks for help everyone
Encrypt the data once with a secure key such as random bytes.
For each user encrypt the above key using the user's password (properly extended), save that in a file or DB under the userID and a salted/hashed password for authentication.
To access lookup the user's entry verify the supplied password with the salted/hashed password, decrypt the data key with the user's password.
Decrypt the data with the data key and return to the user.
Side advantage: A user's password can be changed without changing the actual key the data is encrypted with.
For the second part:
Do not hash(hash(salt + "Thats an amazingly bad password")), use a password extension method such as PBKDF2 on the user supplied password for the encryption key. Such methods take a salt and a password and iterate many times to make the operation slow, somewhere around 100ms seems to be a good target.
Hashing a hash does not accomplish anything other than adding a trivial amount of time to the operation.