Loading core/java/com/android/internal/widget/LockPatternUtils.java +18 −19 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ import android.widget.Button; import com.android.internal.R; import com.google.android.collect.Lists; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import libcore.util.HexEncoding; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; Loading Loading @@ -359,7 +362,7 @@ public class LockPatternUtils { */ public boolean checkPasswordHistory(String password) { String passwordHashString = new String( passwordToHash(password, getCurrentOrCallingUserId())); passwordToHash(password, getCurrentOrCallingUserId()), StandardCharsets.UTF_8); String passwordHistory = getString(PASSWORD_HISTORY_KEY); if (passwordHistory == null) { return false; Loading Loading @@ -860,7 +863,7 @@ public class LockPatternUtils { passwordHistory = ""; } else { byte[] hash = passwordToHash(password, userHandle); passwordHistory = new String(hash) + "," + passwordHistory; passwordHistory = new String(hash, StandardCharsets.UTF_8) + "," + passwordHistory; // Cut it to contain passwordHistoryLength hashes // and passwordHistoryLength -1 commas. passwordHistory = passwordHistory.substring(0, Math.min(hash.length Loading Loading @@ -1040,34 +1043,30 @@ public class LockPatternUtils { * Generate a hash for the given password. To avoid brute force attacks, we use a salted hash. * Not the most secure, but it is at least a second level of protection. First level is that * the file is in a location only readable by the system process. * * @param password the gesture pattern. * * @return the hash of the pattern in a byte array. */ public byte[] passwordToHash(String password, int userId) { if (password == null) { return null; } String algo = null; byte[] hashed = null; try { byte[] saltedPassword = (password + getSalt(userId)).getBytes(); byte[] sha1 = MessageDigest.getInstance(algo = "SHA-1").digest(saltedPassword); byte[] md5 = MessageDigest.getInstance(algo = "MD5").digest(saltedPassword); hashed = (toHex(sha1) + toHex(md5)).getBytes(); } catch (NoSuchAlgorithmException e) { Log.w(TAG, "Failed to encode string because of missing algorithm: " + algo); } return hashed; } byte[] sha1 = MessageDigest.getInstance("SHA-1").digest(saltedPassword); byte[] md5 = MessageDigest.getInstance("MD5").digest(saltedPassword); private static String toHex(byte[] ary) { final String hex = "0123456789ABCDEF"; String ret = ""; for (int i = 0; i < ary.length; i++) { ret += hex.charAt((ary[i] >> 4) & 0xf); ret += hex.charAt(ary[i] & 0xf); byte[] combined = new byte[sha1.length + md5.length]; System.arraycopy(sha1, 0, combined, 0, sha1.length); System.arraycopy(md5, 0, combined, sha1.length, md5.length); final char[] hexEncoded = HexEncoding.encode(combined); return new String(hexEncoded).getBytes(StandardCharsets.UTF_8); } catch (NoSuchAlgorithmException e) { throw new AssertionError("Missing digest algorithm: ", e); } return ret; } /** Loading services/core/java/com/android/server/MountService.java +8 −7 Original line number Diff line number Diff line Loading @@ -76,9 +76,8 @@ import com.android.server.pm.PackageManagerService; import com.android.server.pm.UserManagerService; import com.google.android.collect.Lists; import com.google.android.collect.Maps; import libcore.util.HexEncoding; import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.DecoderException; import org.xmlpull.v1.XmlPullParserException; import java.io.File; Loading Loading @@ -2158,10 +2157,10 @@ class MountService extends IMountService.Stub private String toHex(String password) { if (password == null) { return new String(); return ""; } byte[] bytes = password.getBytes(StandardCharsets.UTF_8); return new String(Hex.encodeHex(bytes)); return new String(HexEncoding.encode(bytes)); } private String fromHex(String hexPassword) { Loading @@ -2169,12 +2168,14 @@ class MountService extends IMountService.Stub return null; } final byte[] bytes; try { byte[] bytes = Hex.decodeHex(hexPassword.toCharArray()); return new String(bytes, StandardCharsets.UTF_8); } catch (DecoderException e) { bytes = HexEncoding.decode(hexPassword.toCharArray(), false); } catch (IllegalArgumentException e) { return null; } return new String(bytes, StandardCharsets.UTF_8); } @Override Loading Loading
core/java/com/android/internal/widget/LockPatternUtils.java +18 −19 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ import android.widget.Button; import com.android.internal.R; import com.google.android.collect.Lists; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import libcore.util.HexEncoding; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; Loading Loading @@ -359,7 +362,7 @@ public class LockPatternUtils { */ public boolean checkPasswordHistory(String password) { String passwordHashString = new String( passwordToHash(password, getCurrentOrCallingUserId())); passwordToHash(password, getCurrentOrCallingUserId()), StandardCharsets.UTF_8); String passwordHistory = getString(PASSWORD_HISTORY_KEY); if (passwordHistory == null) { return false; Loading Loading @@ -860,7 +863,7 @@ public class LockPatternUtils { passwordHistory = ""; } else { byte[] hash = passwordToHash(password, userHandle); passwordHistory = new String(hash) + "," + passwordHistory; passwordHistory = new String(hash, StandardCharsets.UTF_8) + "," + passwordHistory; // Cut it to contain passwordHistoryLength hashes // and passwordHistoryLength -1 commas. passwordHistory = passwordHistory.substring(0, Math.min(hash.length Loading Loading @@ -1040,34 +1043,30 @@ public class LockPatternUtils { * Generate a hash for the given password. To avoid brute force attacks, we use a salted hash. * Not the most secure, but it is at least a second level of protection. First level is that * the file is in a location only readable by the system process. * * @param password the gesture pattern. * * @return the hash of the pattern in a byte array. */ public byte[] passwordToHash(String password, int userId) { if (password == null) { return null; } String algo = null; byte[] hashed = null; try { byte[] saltedPassword = (password + getSalt(userId)).getBytes(); byte[] sha1 = MessageDigest.getInstance(algo = "SHA-1").digest(saltedPassword); byte[] md5 = MessageDigest.getInstance(algo = "MD5").digest(saltedPassword); hashed = (toHex(sha1) + toHex(md5)).getBytes(); } catch (NoSuchAlgorithmException e) { Log.w(TAG, "Failed to encode string because of missing algorithm: " + algo); } return hashed; } byte[] sha1 = MessageDigest.getInstance("SHA-1").digest(saltedPassword); byte[] md5 = MessageDigest.getInstance("MD5").digest(saltedPassword); private static String toHex(byte[] ary) { final String hex = "0123456789ABCDEF"; String ret = ""; for (int i = 0; i < ary.length; i++) { ret += hex.charAt((ary[i] >> 4) & 0xf); ret += hex.charAt(ary[i] & 0xf); byte[] combined = new byte[sha1.length + md5.length]; System.arraycopy(sha1, 0, combined, 0, sha1.length); System.arraycopy(md5, 0, combined, sha1.length, md5.length); final char[] hexEncoded = HexEncoding.encode(combined); return new String(hexEncoded).getBytes(StandardCharsets.UTF_8); } catch (NoSuchAlgorithmException e) { throw new AssertionError("Missing digest algorithm: ", e); } return ret; } /** Loading
services/core/java/com/android/server/MountService.java +8 −7 Original line number Diff line number Diff line Loading @@ -76,9 +76,8 @@ import com.android.server.pm.PackageManagerService; import com.android.server.pm.UserManagerService; import com.google.android.collect.Lists; import com.google.android.collect.Maps; import libcore.util.HexEncoding; import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.DecoderException; import org.xmlpull.v1.XmlPullParserException; import java.io.File; Loading Loading @@ -2158,10 +2157,10 @@ class MountService extends IMountService.Stub private String toHex(String password) { if (password == null) { return new String(); return ""; } byte[] bytes = password.getBytes(StandardCharsets.UTF_8); return new String(Hex.encodeHex(bytes)); return new String(HexEncoding.encode(bytes)); } private String fromHex(String hexPassword) { Loading @@ -2169,12 +2168,14 @@ class MountService extends IMountService.Stub return null; } final byte[] bytes; try { byte[] bytes = Hex.decodeHex(hexPassword.toCharArray()); return new String(bytes, StandardCharsets.UTF_8); } catch (DecoderException e) { bytes = HexEncoding.decode(hexPassword.toCharArray(), false); } catch (IllegalArgumentException e) { return null; } return new String(bytes, StandardCharsets.UTF_8); } @Override Loading