Thursday, 31 October 2013

User authentication on Android against hashed passwords created with Asp.Net Identity

Leave a Comment
Microsoft shipped a new membership system called ASP.NET Identity with Visual Studio 2013 and .Net 4.5.1. It allows us to add login features to the applications built for the web, phone, or store.
By default the ASP.NET Identity system will store all the user information in a database. ASP.NET Identity uses Entity Framework Code First to implement all of its persistence mechanism.

What if we going to build an Android app with offline capabilities, where the users would sync the stored credentials created by Asp.Net Identity on the server in order to login? We would have to verify the provided user password against locally stored hashed password to authenticate the user.
Below is the code that can be used for this task:

/**
  * Verifies provided plain text password against hash 
  * @param hashedPass
  * @param password
  * @return true or false
  */
 private boolean verifyPassword(String hashedPass, String password){
  if (hashedPass == null){
   return false;
  }
  
  byte[] numArray = Base64.decode(hashedPass.getBytes(), Base64.DEFAULT);
  if (numArray.length != 49 || (int) numArray[0] != 0){
         return false;
  }
  
  byte[] salt = new byte[16];
  System.arraycopy(numArray, 1, salt, 0, 16);
  
  byte[] a = new byte[32];
  System.arraycopy(numArray, 17, a, 0, 32);
     
  byte[] b = generateHash(password, salt);     
     
     return Arrays.equals(a, b);
  
 }
 
 /**
  * Generates a hash using PBKDF2WithHmacSHA1 algorithm 
  * @param password
  * @param salt
  * @return hash as byte array
  */
 private byte[] generateHash(String password, byte[] salt) {
  

  SecretKeyFactory secretKeyFactory = null;
  try {
   secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  }    
  KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 1000, 256);    
  SecretKey secretKey = null;
  try {
   secretKey = secretKeyFactory.generateSecret(keySpec);
  } catch (InvalidKeySpecException e) {
   e.printStackTrace();
  }
  
  return secretKey.getEncoded();
 }

And then that can be called from some login activity:

boolean result = verifyPassword("AL09HpS8X96sH4rQjeBqrZJ4Daw+Fr4yFdLjNRLNlFZsrjxsvoRGTlICO0wnBg5N7Q==", "mypass");

0 comments:

Post a Comment