首页 编程 软件学院 查看内容

移动APP如何保存用户密码

2015-3-19 16:19 956 0

摘要: [java] view plaincopyprint?<span style="font-size:14px;">为了更好的用户体验,移动APP客户端一般都会将用户信息进行保存以...
关键词: nbsp 加密 password Hash 密码 登录 客户端 salt 对称 String

[java] view plaincopyprint?<span style="font-size:14px;">为了更好的用户体验,移动APP客户端一般都会将用户信息进行保存以便后续可以自动登录.</span>   保存了用户信息便涉及到了安全问题. 解决的方法大概有一下几种: 1.首先,如果客户端和服务端都是你来设计开发,那么有两种比较可靠的方案 A.客户端将密码Hash加密,登录成功后将hash值保存到Sqlite.服务端得到用户名和hash值,采用同样的算法对密码进行Hash运算,然后和用户传来的hash值进行比较,一致则登录成功.更加可靠的是对密码加盐加密.例如可以采用PBKDF2加盐加密. [java] view plaincopyprint?<span style="font-size:14px;">public static String createHash(String password)              throws NoSuchAlgorithmException, InvalidKeySpecException {          return createHash(password.toCharArray());      }        /**      * Returns a salted PBKDF2 hash of the password.      *       * @param password      *            the password to hash      * @return a salted PBKDF2 hash of the password      */      public static String createHash(char[] password)              throws NoSuchAlgorithmException, InvalidKeySpecException {          // Generate a random salt          SecureRandom random = new SecureRandom();          byte[] salt = new byte[SALT_BYTE_SIZE];          random.nextBytes(salt);            // Hash the password          byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);          return PBKDF2_ITERATIONS + ":" + toHex(salt) + ":" + toHex(hash);      }</span>   加密后的字符串为1000:1507039de0a3c2c88ddf896233278e37d05fd8a0fadc570d:99222374678d4afe5d7d9bf9be4786e17f045ac217c6a2ca, 1000为迭代的次数,后面分别是salt和hash值. 服务端得到这个字符串后,从中解析出迭代次数,salt,hash1值,然后采用同样的算法对数据库里面的密码进行计算 [java] view plaincopyprint?public static boolean validatePassword(String password, String correctHash)          throws NoSuchAlgorithmException, InvalidKeySpecException {      return validatePassword(password.toCharArray(), correctHash);  }    /**  * Validates a password using a hash.  *   * @param password  *            the password to check  * @param correctHash  *            the hash of the valid password  * @return true if the password is correct, false if not  */  public static boolean validatePassword(char[] password, String correctHash)          throws NoSuchAlgorithmException, InvalidKeySpecException {      // Decode the hash into its parameters      String[] params = correctHash.split(":");      int iterations = Integer.parseInt(params[ITERATION_INDEX]);      byte[] salt = fromHex(params[SALT_INDEX]);      byte[] hash = fromHex(params[PBKDF2_INDEX]);      // Compute the hash of the provided password, using the same salt,      // iteration count, and hash length      byte[] testHash = pbkdf2(password, salt, iterations, hash.length);      // Compare the hashes in constant time. The password is correct if      // both hashes match.      return slowEquals(hash, testHash);  }   如果hash2和hash1一致,则登录成功.同时客户端将加密后的字符串保存到本地数据库,下次登录时直接从数据库读取. B.使用非对称加密算法对密码进行加密. 客户端使用公钥加密密码,得到加密串,然后将其发送到服务端.服务端使用私钥解密密码,进行验证,登录成功后,客户端将加密串保存到本地,便于下次自动登录; 使用非对称加密比较可靠,即使加密串被泄露也无法得到密码. 2.如果你只是负责客户端,对服务端无能为力,那么你可能只能使用对称加密了.(如你正在为学校图书馆写个客户端,你还想设置自动登录,那么你本地只能使用对称加密了,将加密串保存到本地,然后下次自动登录时,从数据库取出加密串然后解密...服务端只识别原始的密码) 这种情况,你只能考虑如何生成加密密钥,以及如何保存密钥,如何混淆. 考虑了一种方法: 加解密函数 DES(passwd,key,encode); str1 =  DES(passwd,key,encode); str2 =  DES(key,str1,encode); 本地数据库中保存 str1:str2. 解密时,str2以str1解密得到key. 然后,str1以key解密得到passwd. 非对称加密只能以这种逻辑上的复杂度增加密码的强度.
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部