zoukankan      html  css  js  c++  java
  • 移动APP怎样保存用户password

    <span style="font-size:14px;">为了更好的用户体验,移动APPclient一般都会将用户信息进行保存以便兴许能够自己主动登录.</span>

    保存了用户信息便涉及到了安全问题.

    解决办法大概有一下几种:

    1.首先,假设client和服务端都是你来设计开发,那么有两种比較可靠的方案

    A.client将passwordHash加密,登录成功后将hash值保存到Sqlite.服务端得到username和hash值,採用相同的算法对password进行Hash运算,然后和用户传来的hash值进行比較,一致则登录成功.更加可靠的是对password加盐加密.比如能够採用PBKDF2加盐加密.

    <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值,然后採用相同的算法对数据库里面的password进行计算

    	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一致,则登录成功.同一时候client将加密后的字符串保存到本地数据库,下次登录时直接从数据库读取.

    B.使用非对称加密算法对password进行加密.

    1. client使用公钥加密password,得到加密串,然后将其发送到服务端.
    2. 服务端使用私钥解密password。进行验证,
    3. 登录成功后,client将加密串保存到本地,便于下次自己主动登录;
    使用非对称加密比較可靠。即使加密串被泄露也无法得到password.

    2.假设你仅仅是负责client。对服务端无能为力,那么你可能仅仅能使用对称加密了.(如你正在为学校图书馆写个client。你还想设置自己主动登录。那么你本地仅仅能使用对称加密了,将加密串保存到本地。然后下次自己主动登录时。从数据库取出加密串然后解密...服务端仅仅识别原始的password)
    这样的情况。你仅仅能考虑怎样生成加密密钥,以及怎样保存密钥,怎样混淆.
    考虑了一种方法:
    加解密函数 DES(passwd,key,encode);
    str1 =  DES(passwd,key,encode);
    str2 =  DES(key,str1,encode);
    本地数据库中保存 str1:str2.
    解密时,str2以str1解密得到key.
    然后。str1以key解密得到passwd.
    非对称加密仅仅能以这样的逻辑上的复杂度添加password的强度.

    3. 使用JNI加解密。

    另參考文章:

    android中使用jni对字符串加解密实现分析

    加盐password哈希:怎样正确使用





  • 相关阅读:
    CF 986A Fair——多源bfs
    poj3539 Elevator——同余类bfs
    poj3463 Sightseeing——次短路计数
    poj2262 Goldbach's Conjecture——筛素数
    Kruskal算法
    Prim算法
    离散化
    最短路(hdu2544)
    最短路径问题
    Servlet
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7190220.html
Copyright © 2011-2022 走看看