C# Security – Reinforcing Unique Security Answers and Encryption

asp.net-mvcasp.net-mvc-4authenticationc

When my users are creating an account they need to fill and set several security questions pertaining to their account. I am wondering, how can I make sure that the answer the user enters for each security question is not the same as an answer for a different question? What's the proper attribute for it?

Also, for the security question answers, should I encrypt the answers so that whoever is sniffing the network won't see the answers? How? What should I look into or lookup for this approach?

Best Answer

If you are making a standard web app, then TLS is your only "safe" method of protecting users from MitM attacks and traffic sniffing. Take a look at ipviking's map of real time cyber attacks; a large number come from China because encryption is largely outlawed and browser requests can get hijacked. (Most infosec guys I know agree that X.509 is broken, the IETF is compromised, TLS is likely weakened intentionally by the NSA (kinda like this), and the entire key spaces for RSA and elliptic curves are being precomputed by governments. Nevertheless, it is still better than unencrypted traffic.)

If you must use security questions, I suggest putting everything in lowercase, stripping out whitespace, and hashing with a random salt stored along side it (it could be a single salt stored as part of a user record). I suggest at least 256 bit hash and 100 rounds (fewer if hash algorithm is already slow). Bcrypt hashes are also quite good because they involve encrypting a hash and storing the salt as part of the hash string.

If not using bcrypt, then be sure to not use a simple str1==str2 boolean for checking the answer; you should use something like the following, which will avoid the string comparison side channel attack.

function compHashes ($h1, $h2) {
    $r = 0;
    if (strlen($h1) !== strlen($h2)) return false;
    for ($i=0; $i<strlen($h1); ++$i)
        $r |= ord($h1[$i])^ord($h2[$i]);
    return $r == 0;
}

The considerations for binary apps are a little different in that you can hard code or bundle a public key (or several) and use NaCl to generate client private keys and handle handshakes and encryption between server and client. There are libraries in every compilable language for this, and writing a wrapper for a statically linked library is not too difficult if that is the route you choose. Rolling your own crypto is definitely not recommended if you are not very familiar with cryptography and infosec matters.

Related Topic