Will appending session id to a password prior an RSA encryption introduce vulnerability where an eavesdropper can collect multiple encrypted password ciphertext and perform cryptanalysis to obtain the password? (Session id is known to the server only and unique for each visitor)

Background story

I have a login form that encrypts passwords using client-side (Javascript) RSA encryption and sends the encrypted passwords to backend server (PHP) to be decrypted and then sent to be authenticated by an LDAP server. This is to prevent any eavesdroppers from snatching the passwords should they be sent in plaintexts.

However, I have a feeling that if there was indeed an eavesdropper, he/she does not even have to know the passwords as he/she can just forge a request using the encrypted passwords (i.e. replay attack).

So I'm planning to improve the scheme by prepending/appending users' session id to plain passwords before encrypting them on the client-side. That way, even if an eavesdropper forges a request using an encrypted password, the backend server can check if the session id in the decrypted string does not match with the attacker's session id and hence reject the login request.

However, I have a feeling that an eavesdropper that monitors a particular user's login requests can take multiple versions of the encrypted passwords and perform cryptanalysis to obtain the plain password, something that would not be possible if the encrypted passwords remain the same in all the requests (which in turn is susceptible to a replay attack).

Is my worry a valid concern?

N.B.: Assume that HTTPS/SSL is not an option for my case.


You are absolutely correct. If you hash or encrypt the password on the client, then pass the resulting digest over an un-encrypted channel, then any man in the middle can simply replay the digest value and log in. The original password is irrelevant now.

What you have effectively done is to turn the digest itself into the password.

The real issue is that you are not using HTTPS to protect your session. The underlying issue is a trustworthy exchange of encryption keys between the client and the server (an offline component of the encryption). This is the exact issue that HTTPS (SSL/TLS) addresses. I'm afraid that by doing your password encryption/hashing on the client and passing the resulting values over a plaintext channel, you're doomed to create a system that is either vulnerable to replay attacks, or too expensive to implement and maintain as a secure system into the future.

Why is HTTPS not an option? If security is the goal, I think HTTPS is probably your only reasonable option.

Your general approach was immortalized in an official Internet RFC 20 years ago, and has been known to be kind of broken for a very long time. Just read about HTTP digest authentication: https://tools.ietf.org/html/rfc2617

Regarding appending a session id... First, what does that matter if the channel is unencrypted and the attacker can just replay the digest (unless you are changing the session id on every call)? Also, there is is no magical session id--if the id is known to the server, then either the server or the client created it and passed it across the wire. So the session id isn't a secret.

To protect this kind of scheme at all, you need to use a nonce. You need to send your encrypted authentication package with every request, and you need to increment the nonce and re-encrypt for every call. That way, the server can see that the nonce is larger than it was on the last request, and thus reject a replay. So now the server has to track that nonce value, per user, in addition to the session id. That becomes more complicated if you have a web garden or server farm, because you have to update that shared state centrally, and that can become a scalability and concurreny issue for your system. And there are still more issues with a scheme like this, which is why one of the factors in the Kerberos authentication schema (for example), is that the server and the client must have their clocks synchronized within 5 minutes of eachother. Among other things, a simple incrementing nonce can leave you vulnerable to attackers with a lot of resources.

You're also doing this in JavaScript in your client, communicating over an unencrypted channel, thus making your system even more susceptible to things like script injection, meaning that some rogue JavaScript in the page could read out values of variables in your security script, including the value of the original password, and phone that information back home to whoever is listening. Do you completely trust every analytics script you include in your pages? Do you completely trust that some new XSS attack can't put a bad guy's JavaScript in your page?

And so on. If you want actual security, you need to implement something more in the league of Kerberos (which is heady stuff), and you probably need to implement it as a browser plugin to provide a bit of a wall between it and other scripts and plugins.

Or you just need to implement HTTPS, and send the password through the encrypted channel to the server, where the server will salt it, hash it (hopefully using an algorithm like scrypt, bcrypt or pbkdf2) and compare it to the digest you have stored on the server.

Otherwise, I'm afraid you're not accomplishing real security.


No, that's not a problem if you use the correct padding scheme such as OAEP. OAEP protects the scheme against known plaintext attack.

What is a problem is the issue that the public key is probably not trusted by the client. The client cannot see if the public key is send by an attacker or by your server. This allows impersonation and man-in the-middle attacks.

This cannot be fully solved without some off line authentication. TLS solves this issue using the security provided by the browser itself and the trust store included with the browser.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.