Encrypting Register Information Sent to Database

Need help with SmartFoxServer? You didn't find an answer in our documentation? Please, post your questions here!

Moderators: Lapo, Bax

Guy71173cp
Posts: 148
Joined: 03 Aug 2010, 16:08
Contact:

Encrypting Register Information Sent to Database

Postby Guy71173cp » 23 Jun 2012, 18:03

Hello.

When a user registers, how could I use MD5 to encrypt the database? I read the docs on encrypting the user list array, but how would I encrypt an actual database? I'm using the H2 database. Here is my register extension:

Code: Select all

function handleRequest(cmd, params, user, fromRoom) {
   if (cmd == "register") {
      var userName = params.uName;
      var passWord = params.pass;
      var email = params.email;
      var response = {};
      response._cmd = "register";
      var error = "";
      var success = false;
      var sql = "SELECT COUNT (NAME) FROM USERS WHERE NAME='"+_server.escapeQuotes(userName)+"'";
      var sql2 = "SELECT COUNT (NAME) FROM QUESTS WHERE NAME='"+_server.escapeQuotes(userName)+"'";
      var queryRes = dbase.executeQuery(sql);
      var queryRes2 = dbase.executeQuery(sql2);
      if (queryRes != null) {
         if (queryRes2 != null) {
            var Row = queryRes.get(0);
            var count = Row.getItem("COUNT(NAME)");
            if (count == 0) {
               sql = "INSERT INTO USERS (NAME, PASS, EMAIL, COINS) VALUES ('"+userName+"', '"+passWord+"', '"+email+"', '"+1000+"')";
               sql2 = "INSERT INTO QUESTS (NAME,QUEST) VALUES ('"+userName+"', '"+1+"')";
               queryRes = dbase.executeCommand(sql);
               queryRes2 = dbase.executeCommand(sql2);
               success = true;
            } else {
               trace("USERNAME ALREADY REGISTERED!");
               error = "That username is already registered.";
            }
         } else {
            error = "Cannot connect to the database";
         }
      }
      response.error = error;
      response.success = success;
      _server.sendResponse(response, -1, null, [user]);
   }


I have no idea how to insert the password to the database encrypted. Any help is appreciated. Thanks.
User avatar
rjgtav
Posts: 2813
Joined: 19 Apr 2009, 11:31
Location: Lisbon, Portugal

Re: Encrypting Register Information Sent to Database

Postby rjgtav » 23 Jun 2012, 18:49

Hi.
SFS1X already comes with MD5 support on the server-side, which you can find here.
In order to better understand how to use Java classes on AS extensions, you can check this chapter of the documentation.
Skills: SFS Pro, SFS2X, AS2.0/AS3.0, Java, HTML5/CSS3/JS, C#
Portfolio: https://rjgtav.wordpress.com/
SFS Tutorials: http://sfs-tutor.blogspot.com/ - Discontinued. Some examples may be bugged.
Guy71173cp
Posts: 148
Joined: 03 Aug 2010, 16:08
Contact:

Re: Encrypting Register Information Sent to Database

Postby Guy71173cp » 23 Jun 2012, 23:04

But how would I send the MD5 encryption to the database in the insert SQL statement in the extension? And how would I convert the password to MD5? Because that one article you told me about (the one with talking about MD5) didn't have much information on using it. Would I use something like this:

Code: Select all

 var key = _server.getSecretKey(socketChannel)
                var md5 = _server.md5(key + passWord)

and then the normal insert code? Thanks and if you know of another article with more information and detail on MD5 I'd like to see it. Thanks a lot.
User avatar
rjgtav
Posts: 2813
Joined: 19 Apr 2009, 11:31
Location: Lisbon, Portugal

Re: Encrypting Register Information Sent to Database

Postby rjgtav » 24 Jun 2012, 00:19

In order to get the MD5 hash, you first have to get an instance of the MD5 class, by doing:

Code: Select all

var md5 = Packages.it.gotoandplay.smartfoxserver.crypto.MD5.instance();

Then, in order to get the hash, you simply call the getHash method:

Code: Select all

var hashedPassword = md5.getHash("myPassword");
Skills: SFS Pro, SFS2X, AS2.0/AS3.0, Java, HTML5/CSS3/JS, C#
Portfolio: https://rjgtav.wordpress.com/
SFS Tutorials: http://sfs-tutor.blogspot.com/ - Discontinued. Some examples may be bugged.
Guy71173cp
Posts: 148
Joined: 03 Aug 2010, 16:08
Contact:

Re: Encrypting Register Information Sent to Database

Postby Guy71173cp » 05 Jul 2012, 22:35

Ok, so I create these variables on the client in the register coding:

Code: Select all

smartfox.onJoinRoom = function(r:Room) {
   if (task == "register") {
      var md5 = Packages.it.gotoandplay.smartfoxserver.crypto.MD5.instance();
      var hashedPassword = md5.getHash(passWord.text);
      _root["registerWindow"].error.text = "Registering...";
      smartfox.sendXtMessage("DatabaseRegisterExt", "register", _root.registerObj,hashedPassword);
   }
};
                 


Then, on the serverside, I changed the var passWord:

Code: Select all

if (cmd == "register") {
      var userName = params.uName;
      var passWord = params.hashedPassword;
      var email = params.email;


Then it registers. I almost have it working, except in the password column in the database, the user's password is undefined. I traced params.hashedPassword on the server side and got undefined. What am I doing wrong? If I'm doing this completely wrong, please tell me the process and how the md5 works. Thanks.
User avatar
rjgtav
Posts: 2813
Joined: 19 Apr 2009, 11:31
Location: Lisbon, Portugal

Re: Encrypting Register Information Sent to Database

Postby rjgtav » 07 Jul 2012, 12:48

You have to create the MD5 Hash on the server-side, not on the client side
Skills: SFS Pro, SFS2X, AS2.0/AS3.0, Java, HTML5/CSS3/JS, C#
Portfolio: https://rjgtav.wordpress.com/
SFS Tutorials: http://sfs-tutor.blogspot.com/ - Discontinued. Some examples may be bugged.
Guy71173cp
Posts: 148
Joined: 03 Aug 2010, 16:08
Contact:

Re: Encrypting Register Information Sent to Database

Postby Guy71173cp » 07 Jul 2012, 19:45

Oh hey thanks, it works! So, how can I check the MD5 to see if the passes match? I made an account, with 2 letters (I just put gg and gg as pass for testing) and it's password was converted to md5 in the database. Now in the login extension, I have 2 lines of code:

Code: Select all

var key = _server.getSecretKey(SocketChannel)
      var md5 = _server.md5(key + userName[userName])


And below, I have:

Code: Select all

if(md5 == passWord){
                  if (item.LOGGEDIN == "FALSE") {
                     trace("SUCCESSFULL LOGIN");
                     var obj = _server.loginUser(userName, passWord, SocketChannel);
                     if (obj.success) {
                        var u = _server.instance.getUserByChannel(SocketChannel);
                        response.userId = u.getUserId();
                        response._cmd = "logOK";
                        response.name = userName;
                        response.LOGGEDIN = "TRUE";
                     } else {
                        _global.error = obj.error;
                        response._cmd = "logKO";
                     }


But I still get incorrect password. I'm positive it's that the server isn't reading the md5 and finding out the raw password. Do you know how to get around this? And also it's salted, so what else do I have to do to check it? Thanks.
User avatar
rjgtav
Posts: 2813
Joined: 19 Apr 2009, 11:31
Location: Lisbon, Portugal

Re: Encrypting Register Information Sent to Database

Postby rjgtav » 08 Jul 2012, 11:51

Oh, you're using the secure login tutorial...
First, you may know that the MD5 is a one way only encryption method, which means that you can't get the original password from the generated hash.

If you store the password encrypted on the database, then you will need to hash the password 2 times on the client: you have to first hash the string that was written in the password textfield and then you'll need to hash again that hashed password with the secret key which you got from the server-side.
Then, the way to verify if the password is correct is the same as explained in the Secure Login Tutorial: you first hash the password stored in the database with the secret key and then check if the result matches with the password that was sent.

You can check the secureLogin example's fla in order to find out how to create a MD5 hash on the client-side
Skills: SFS Pro, SFS2X, AS2.0/AS3.0, Java, HTML5/CSS3/JS, C#
Portfolio: https://rjgtav.wordpress.com/
SFS Tutorials: http://sfs-tutor.blogspot.com/ - Discontinued. Some examples may be bugged.
Guy71173cp
Posts: 148
Joined: 03 Aug 2010, 16:08
Contact:

Re: Encrypting Register Information Sent to Database

Postby Guy71173cp » 08 Jul 2012, 17:14

Hmmm, I'm a little confused. So what you're saying is, when the user registers, I hash it on the client first with

Code: Select all

var pass:String = passWord.text   
var md5:String = hex_md5(_global.key + pass)

Then, I send the md5 variable to the server-side extension, the server hashes it again but adds the security key to it, then it adds the encrypted pass to the database? Sorry, I'm a little confused. Thanks for the help!
User avatar
rjgtav
Posts: 2813
Joined: 19 Apr 2009, 11:31
Location: Lisbon, Portugal

Re: Encrypting Register Information Sent to Database

Postby rjgtav » 08 Jul 2012, 19:05

No... You can't hash the password with the secret key when you are registering, otherwise that password will never work, as the secret key is always unique.
When you're registering, you simply hash the password one time, which can be on either the client-side or the server-side (on the server-side is more secure) and with no secret key.

Only at the login time is when you need to hash the password with no secret key and after that hash it again with the secret key. Then on the server-side you also hash the password you get from the database with the secret key, and compare both passwords.
Skills: SFS Pro, SFS2X, AS2.0/AS3.0, Java, HTML5/CSS3/JS, C#
Portfolio: https://rjgtav.wordpress.com/
SFS Tutorials: http://sfs-tutor.blogspot.com/ - Discontinued. Some examples may be bugged.
Guy71173cp
Posts: 148
Joined: 03 Aug 2010, 16:08
Contact:

Re: Encrypting Register Information Sent to Database

Postby Guy71173cp » 18 Jul 2012, 19:35

Hello.

Ok. But I'm still confused. Do I only send the encrypted pass to the extension? Or the encrypted and unencrypted pass? Here's the extension:

Code: Select all

if (evt.name == "loginRequest") {
      trace("yeah");
      _global.error = "";
      userName = evt["nick"];
      passWord = evt["pass"];
      SocketChannel = evt["chan"];
      
      
      var sql = "SELECT COUNT (NAME) FROM DONUTISLANDACCOUNTS WHERE NAME='"+userName+"' AND PASS='"+passWord+"'";
      var sql2 = "SELECT * FROM DONUTISLANDACCOUNTS WHERE NAME='"+userName+"'";
      var queryRes = dbase.executeQuery(sql);
      var queryRes2 = dbase.executeQuery(sql2);
      var key = _server.getSecretKey(SocketChannel);
      var md5 = _server.md5(key+passWord);
      var response = {};
      if (queryRes != null) {
         if (queryRes2 != null) {
            for (var i = 0; i<queryRes2.size(); i++) {
               var tempRow = queryRes2.get(i);
               var item = {};
               item.NAME = tempRow.getItem("NAME");
               item.LOGGEDIN = tempRow.getItem("LOGGEDIN");
               trace(item.NAME);
               trace(item.LOGGEDIN);
               var Row = queryRes.get(0);
               var count = Row.getItem("COUNT(NAME)");
               var clientmd5 = tempRow.getItem("PASS")
               if(md5 == clientmd5){
               //if (count == 1) {
                  if (item.LOGGEDIN == "FALSE") {
                     trace("SUCCESSFULL LOGIN");
                     //var sql2 = "UPDATE DONUTISLANDACCOUNTS SET";
                     //sql2 += " LOGGEDIN='"+_server.escapeQuotes("TRUE")+"'";
                     //sql2 += " WHERE NAME='"+_server.escapeQuotes(userName)+"'";
                     //dbase.executeCommand(sql2);
                     var obj = _server.loginUser(userName, passWord, SocketChannel);
                     if (obj.success) {
                        var u = _server.instance.getUserByChannel(SocketChannel);
                        response.userId = u.getUserId();
                        response._cmd = "logOK";
                        response.name = userName;
                        response.LOGGEDIN = "TRUE";
                     } else {
                        _global.error = obj.error;
                        response._cmd = "logKO";
                     }
                  } else if (item.LOGGEDIN == "TRUE") {
                     response._cmd = "logKO";
                     _global.error = "Your already logged in on a different server. Please log out and try again.";
                  }
               } else if (count == 0) {
                  trace("FAILED LOGIN");
                  response._cmd = "logKO";
                  _global.error = "Wrong username or password";
               } else {
                  response._cmd = "logKO";
                  _global.error = "Error connecting to database.";
               }

I have this on the client:

Code: Select all

var pass:String = passWord.text;
         var clientmd5:String = hex_md5(_global.key+pass);
         smartfox.login(originalZone, userName.text,clientmd5);


But for some reason I always get incorrect username or password. What am I doing wrong? Thanks.
User avatar
rjgtav
Posts: 2813
Joined: 19 Apr 2009, 11:31
Location: Lisbon, Portugal

Re: Encrypting Register Information Sent to Database

Postby rjgtav » 18 Jul 2012, 20:34

Lets think about it nice and easily...
Maybe you should try by doing the secure login with non-encrypted password on the database.
Image
As you can see in that image, the 1st step is to request the random key from the server. So far so good.
Then you have to send from the client the raw password encoded with the key (by generating a MD5 hash).

On the server-side, when you get the login request, you also generate a md5 hash with the raw password you get from the database and the secret key.

Finally, if you have done everything correctly on both the server and the client sides, then both hashes should be equal.

Now for storing encrypted passwords on the database, you just have to hash the "raw password" before actually hashing it with the secret key.
Skills: SFS Pro, SFS2X, AS2.0/AS3.0, Java, HTML5/CSS3/JS, C#
Portfolio: https://rjgtav.wordpress.com/
SFS Tutorials: http://sfs-tutor.blogspot.com/ - Discontinued. Some examples may be bugged.
Guy71173cp
Posts: 148
Joined: 03 Aug 2010, 16:08
Contact:

Re: Encrypting Register Information Sent to Database

Postby Guy71173cp » 28 Jul 2012, 17:01

I got it working! But, when you register, I have also added a salt. How would I check that? Is it safe to add the salt variable to the client? I was thinking it could go like this:

1. Encrypt password with salt and key on the client.

2. Send encrypted and salted pass to the extension and the extension salts, encrypts, and adds the security key to the raw password.

3. The extension matches them to see if they are correct.

So this is my question: Is it safe to add the salt variable to the client?
User avatar
rjgtav
Posts: 2813
Joined: 19 Apr 2009, 11:31
Location: Lisbon, Portugal

Re: Encrypting Register Information Sent to Database

Postby rjgtav » 30 Jul 2012, 11:56

Well, I wouldn't advise to add a salt when hashing the password before storing it on the database... Because in order to this system to work with no problems, you would need to be able to always generate the correct salt based on the client account which is trying to login.
If you store a different salt for each account, it won't provide you any additional security, as you'd also need to store the salt somewhere else, which would also be easily accessed.

The only working way I can find is by using always the same salt variable, which would be stored only on the extension (inside the code), which would increase significantly the time needed for hacking a password, as the hacked would firstly need to find what salt was being used.
The only negative aspect of this approach is that once your salt was discovered, you would need to generate a new salt and reset everyone's password, so that they would register a new password with the new salt.

And no, it never is safe to store anything security related on the client, as one can easily reverse engineer the client and get the source code.
Skills: SFS Pro, SFS2X, AS2.0/AS3.0, Java, HTML5/CSS3/JS, C#
Portfolio: https://rjgtav.wordpress.com/
SFS Tutorials: http://sfs-tutor.blogspot.com/ - Discontinued. Some examples may be bugged.
Guy71173cp
Posts: 148
Joined: 03 Aug 2010, 16:08
Contact:

Re: Encrypting Register Information Sent to Database

Postby Guy71173cp » 30 Jul 2012, 15:46

Hello.

I use the same salt variable everytime. But, how would I compare the two passwords if I don't salt it on the client?

Return to “SmartFoxServer 1.x Discussions and Help”

Who is online

Users browsing this forum: No registered users and 62 guests