{"id":297,"date":"2015-07-17T14:53:35","date_gmt":"2015-07-17T14:53:35","guid":{"rendered":"http:\/\/smartfoxserver.com\/blog\/?p=297"},"modified":"2015-07-17T14:53:35","modified_gmt":"2015-07-17T14:53:35","slug":"login-with-encryption","status":"publish","type":"post","link":"https:\/\/smartfoxserver.com\/blog\/login-with-encryption\/","title":{"rendered":"Login with encryption"},"content":{"rendered":"<p>With SmartFoxServer 2.10 we have added full TLS encryption to the protocol. In this recipe we&#8217;re going to discuss the implications for the Login phase in SFS2X and the differences with\u00a0the previous modality of secure Login.<\/p>\n<p><!--more--><\/p>\n<h3>\u00bb CHAP vs TLS<\/h3>\n<p>The Login phase in SmartFoxServer 2X has always been secure, even prior to the introduction of protocol encryption. For those not entirely familiar with the previous system we used a well known communication scheme called <a title=\"CHAP on Wikipedia\" href=\"https:\/\/en.wikipedia.org\/wiki\/Challenge-Handshake_Authentication_Protocol\" target=\"_blank\">CHAP<\/a> (Challenge-Handshake Authentication Protocol) which can be summarized in these steps:<\/p>\n<ul>\n<li>the client obtains a unique token upon connection<\/li>\n<li>the user&#8217;s password is hashed together with the unique token and sent over the wire<\/li>\n<li>the server retrieves the original password from a datasource (e.g. database), hashes it with the same token and compares it what was sent by the client<\/li>\n<li>If the two hashes are identical the password is correct<\/li>\n<\/ul>\n<p>This system is pretty\u00a0secure as it never transmits the password in clear and the hash will be different in every session, but has one main drawback: it typically forces the developer to keep the users&#8217; password either in clear or hashed in the\u00a0database, not allowing for proper\u00a0<a title=\"Password salt\" href=\"https:\/\/en.wikipedia.org\/wiki\/Salt_(cryptography)\" target=\"_blank\">salting<\/a>.<\/p>\n<p>Using a simple hashing pass is still not good enough, as the passwords need to be quite\u00a0strong in order not be cracked using a reverse-hash database.<\/p>\n<p>With the TLS-encrypted protocol we can overcome these issues because we&#8217;re no longer using an asymmetric encryption technique (i.e. hashing). Instead we&#8217;re using symmetric cryptography (AES 128) with a key that has been exchanged securely over HTTPS.<\/p>\n<p>This in turn means that\u00a0the password no longer\u00a0gets to the other side as a hash which\u00a0caused the\u00a0storage limitations in the first place.<\/p>\n<h3>\u00bb What does this all mean?<\/h3>\n<p>In essence it means that clients&#8217; passwords can be store in your datasources in whatever way your security requirements dictate.<\/p>\n<p>If you want to get more in-depth on the new\u00a0SFS2X protocol encryption,\u00a0we recommend reading our introduction to <a title=\"SFS2X Cryptography\" href=\"http:\/\/docs2x.smartfoxserver.com\/GettingStarted\/cryptography\" target=\"_blank\">SmartFoxServer&#8217;s TLS support<\/a>.<\/p>\n<h3>\u00bb Can I use my old Login code with the new TLS protocol?<\/h3>\n<p>No, there a couple of minor changes that need to be applied to your code. It is all\u00a0very simple and it all boils down to one single parameter which, unsurprisingly, is the <strong>password\u00a0<\/strong>itself.<\/p>\n<p>Let&#8217;s review the pre-2.10 modality of sending a login request.<br \/>\nClient side (C#) we used this:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">sfs.Send(new LoginRequest(&quot;user name&quot;, &quot;password&quot;, &quot;zone name&quot;));<\/pre>\n<p>Server side:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npublic class LoginEventHandler extends BaseServerEventHandler\r\n{\r\n   @Override\r\n   public void handleServerEvent(ISFSEvent event) throws SFSException\r\n   {\r\n      String name = (String) event.getParameter(SFSEventParam.LOGIN_NAME);\r\n      String pass = (String) event.getParameter(SFSEventParam.LOGIN_PASSWORD);\r\n\r\n      if (getApi().checkSecurePassword(session, clearPass, encryptedPass))\r\n      {\r\n \t\t  \/\/ Login success...\r\n      }\r\n\t  else\r\n      {\r\n        \/\/ Create the error code to send to the client\r\n        SFSErrorData errData = new SFSErrorData(SFSErrorCode.LOGIN_BAD_USERNAME);\r\n        errData.addParameter(name);\r\n\r\n        \/\/ Fire a Login exception\r\n        throw new SFSLoginException(&quot;Login error!&quot;, errData);\r\n      }\r\n   }\r\n}\r\n<\/pre>\n<p>With SmartFoxServer 2.10 and higher we need to send the password as a different field in the request. This is because the 2nd parameter in the <strong>LoginRequest<\/strong> is always <span style=\"text-decoration: underline;\">hashed with the unique token<\/span> (as we said in the opening of this article) to maintain compatibility with the previous version.<\/p>\n<p>To bypass the default password field we can simply pass a null value and provide the real user password as a field\u00a0of the SFSObject taken as an optional 4th parameter in the request.<\/p>\n<p>The object is a convenient tool to send any additional custom parameter at login time.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nLoginRequest(string userName, string password, string zoneName, ISFSObject parameters)\r\n<\/pre>\n<h3>\u00bb\u00a0Secure Login 2.0, using TLS encrypted protocol<\/h3>\n<p>Before we move ahead with the code make sure that the Encryption is active in your Zone. If you need guidance for setting this up, please refer to the <a title=\"Setting up cryptography\" href=\"http:\/\/docs2x.smartfoxserver.com\/GettingStarted\/cryptography\" target=\"_blank\">documentation here<\/a>.<\/p>\n<p>This is the client side code (C#):<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nISFSObject params = new SFSObject();\r\nparams.PutUtfString(&quot;password&quot;, &quot;MyPassword123&quot;);\r\n\r\nsfs.Send(&quot;user name&quot;, null, &quot;zone name&quot;, params&quot;);\r\n<\/pre>\n<p>The only difference here is that we&#8217;re wrapping the password in the SFSObject sent as the 4th parameter in the request.<\/p>\n<p>On the server side we can use this code:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npublic class LoginEventHandler extends BaseServerEventHandler\r\n{\r\n   @Override\r\n   public void handleServerEvent(ISFSEvent event) throws SFSException\r\n   {\r\n      String name = (String) event.getParameter(SFSEventParam.LOGIN_NAME);\r\n      ISFSObject params = (ISFSObject) event.getParameter(SFSEventParam.LOGIN_IN_DATA);\r\n\r\n\t  String password = params.getUtfString(&quot;password&quot;);\r\n\r\n      if (password != null &amp;&amp; password.equals(originalPassword))\r\n      {\r\n \t\t  \/\/ Login success...\r\n      }\r\n\t  else\r\n      {\r\n        \/\/ Create the error code to send to the client\r\n        SFSErrorData errData = new SFSErrorData(SFSErrorCode.LOGIN_BAD_USERNAME);\r\n        errData.addParameter(name);\r\n\r\n        \/\/ Fire a Login exception\r\n        throw new SFSLoginException(&quot;Login error!&quot;, errData);\r\n      }\r\n   }\r\n}\r\n<\/pre>\n<p>The difference here is that we first obtain the SFSObject from the request and then proceed by extracting the password. Then\u00a0we can use\u00a0a regular String comparison between what has sent the client and original password retrieved from our data source.<\/p>\n<p>Naturally, while we can access the password in clear in our Extension code, the data has been traveling trough the wire fully\u00a0encrypted.<\/p>\n<h3>\u00bb Using the LoginAssistant Component with a custom password<\/h3>\n<p>For those using the more convenient <strong>LoginAssistant<\/strong>\u00a0we have also updated the component with release 2.10 to make sure the same operation described above is also supported.<\/p>\n<p>Please check the &#8220;Custom password checking and encryption&#8221; <a title=\"Login Assistant docs\" href=\"http:\/\/docs2x.smartfoxserver.com\/DevelopmentBasics\/login-assistant\" target=\"_blank\">section of this doc page<\/a>, to learn more how to use it in conjunction with TLS encryption.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With SmartFoxServer 2.10 we have added full TLS encryption to the protocol. In this recipe we&#8217;re going to discuss the implications for the Login phase in SFS2X and the differences with\u00a0the previous modality of secure Login.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[38,39,7],"_links":{"self":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/297"}],"collection":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/comments?post=297"}],"version-history":[{"count":6,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/297\/revisions"}],"predecessor-version":[{"id":314,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/297\/revisions\/314"}],"wp:attachment":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/media?parent=297"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/categories?post=297"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/tags?post=297"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}