Android14 锁屏密码修改为至少6位
Android14 锁屏密码修改为至少6位
一、前言
最近在搞欧盟 EN18031 无线安全认证,需要优化系统安全。
其实目前还不知道具体需要啥优化,无非是加密和安全那些;
如果是自己的应用保存的密码,进行加密保存就行;
目前认证方提示锁屏密码可以加强,其实这个在EN18031草案好像是建议优化并非强制;
还得做点啥吧,所以最近分析实现了Android原生的锁屏密码修改为至少6位的实现。
Android锁屏密码、pin码、图案密码,默认都是最少四位;
锁屏密码和pin码锁屏的区别:pin码使能是0-9数值,普通锁屏密码可以任意字母+数值。
如果需要修改为最少6位,只要修改两个地方就行了。
看起来很简单,实际需要详细分析Settings锁屏逻辑,最后是修改framework的默认定义。
修改效果:
目前网上搜索的知识和AI的实现都是不行的。
网上的建议修改:frameworks/base/core/java/android/app/admin/DevicePolicyManager.java// 修改设备策略中的最小密码长度默认值public static final int DEFAULT_PASSWORD_MIN_LENGTH = 6; // 原值为4frameworks/base/core/java/com/android/internal/widget/LockPatternUtils.java// 同时修改PIN码最小长度的常量定义public static final int MIN_PASSWORD_LENGTH = 6; // 原值为4public static final int MAX_PASSWORD_LENGTH = 16; // 保持不变frameworks/base/packages/Settings/src/com/android/settings/password/ChooseLockPassword.java// 修改密码输入提示文本private void updatePasswordHint() { // 原提示:mPasswordEntry.setHint(getString(R.string.password_quality_hint, 4)); mPasswordEntry.setHint(getString(R.string.password_quality_hint, 6));}// 修改密码长度验证错误提示private boolean validatePassword(String password) { if (password.length() < 6) { // 原提示:mPasswordEntry.setError(getString(R.string.password_too_short, 4)); mPasswordEntry.setError(getString(R.string.password_too_short, 6)); return false; } return true;}
看起来挺容易的,并且比较可行,但是在Android13、14 源码里面的同样的类找不到这些方法和变量。
所以需要实现这个功能还得具体代码分析,本文简单分析一下具体实现和过程。
这种问题基本没啥人修改和研究,这里简单记录下。
二、修改Android14 锁屏密码修改为至少6位分析实现代码
先说实现代码,因为有些人可能不想看具体分析过程。
1、实现代码
framework\\base\\core\\java\\com\\android\\internal\\widget\\LockPatternUtils.java
/** * Utilities for the lock pattern and its settings. */public class LockPatternUtils { private static final String TAG = \"LockPatternUtils\"; /** * The minimum number of dots in a valid pattern. */ - public static final int MIN_LOCK_PATTERN_SIZE = 4; + public static final int MIN_LOCK_PATTERN_SIZE = 6; /** * The minimum size of a valid password. */- public static final int MIN_LOCK_PASSWORD_SIZE = 4;+ public static final int MIN_LOCK_PASSWORD_SIZE = 6;...}
上面两个的修改分别就是对于锁屏图片和锁屏密码、pin码的位数。
就是这么简单,但是过程需要时间分析。
2、修改过程分析
有AI搜的关键字一个都没有,大概看了下这里看起来有点关系。
public class IccLockSettings extends SettingsPreferenceFragment ... { private static final int MIN_PIN_LENGTH = 4; //修改为6 private static final int MAX_PIN_LENGTH = 8; }
测试了一下不行,搜索后才发现Icc是sim卡管理作用的,和锁屏没啥关系。
所以只能一步步分析了。
(1)找到界面对应的代码
正常界面如下:
Settings应用代码,res\\zh-rCh文件夹找到字符串:
\"{count,plural, =1{PIN 码必须至少包含 # 位数,不过为提高安全性,建议使用 {minAutoConfirmLen} 位数的 PIN 码}other{PIN 码必须至少为 # 位数,不过为提高安全性,建议使用 {minAutoConfirmLen} 位数的 PIN 码}}\"
找到 lockpassword_pin_too_short_autoConfirm_extra_message 字符串的Java代码:
Settings\\src\\com\\android\\settings\\password\\ChooseLockPassword.java
所以主要判断逻辑估计就在 ChooseLockPassword 这个类里面的了。
找到那里定义4的地方就可以了!?
(2) ChooseLockPassword.java 简单分析
public class ChooseLockPassword extends SettingsActivity { private static final String TAG = \"ChooseLockPassword\"; public static class ChooseLockPasswordFragment extends InstrumentedFragment...{ private static final int MIN_AUTO_PIN_REQUIREMENT_LENGTH = 6; ... //1、锁屏相关的布局 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.choose_lock_password, container, false); }}//2、这里是收集各种输入异常的集合 String[] convertErrorCodeToMessages() { List messages = new ArrayList(); //3、遍历所有异常提示 for (PasswordValidationError error : mValidationErrors) { switch (error.errorCode) { case CONTAINS_INVALID_CHARACTERS: messages.add(getString(R.string.lockpassword_illegal_character)); break;... case TOO_SHORT: //4、输入太短 String message = StringUtil.getIcuPluralsString(getContext(), error.requirement, mIsAlphaMode ? R.string.lockpassword_password_too_short : R.string.lockpassword_pin_too_short); if (LockPatternUtils.isAutoPinConfirmFeatureAvailable() && !mIsAlphaMode && error.requirement < MIN_AUTO_PIN_REQUIREMENT_LENGTH) { Map arguments = new HashMap(); arguments.put(\"count\", error.requirement); //5、这里应该是4 ! arguments.put(\"minAutoConfirmLen\", MIN_AUTO_PIN_REQUIREMENT_LENGTH); // 6、这里是数值 6 message = StringUtil.getIcuPluralsString(getContext(), arguments, R.string.lockpassword_pin_too_short_autoConfirm_extra_message); } messages.add(message);//7、PIN 码必须至少包含4个字符串...的提示语 break; ... return messages.toArray(new String[0]); }//8、所以关键是找到 mValidationErrors 错误列表里面的 error.requirement的数值//下面这个方法是ChooseLockPasswordFragment 的验证输入代码逻辑//密码输入框EditText每次输入都会调用这里,检测密码是否符合要求//LockscreenCredential 对象已经封装了密码数据 boolean validatePassword(LockscreenCredential credential) { final byte[] password = credential.getCredential(); //9、最关键的判断:PasswordMetrics.validatePassword mValidationErrors = PasswordMetrics.validatePassword( mMinMetrics, mMinComplexity, !mIsAlphaMode, password); //这个基本不会进入! if (mValidationErrors.isEmpty() && mLockPatternUtils.checkPasswordHistory( password, getPasswordHistoryHashFactor(), mUserId)) { mValidationErrors = Collections.singletonList(new PasswordValidationError(RECENTLY_USED)); } //10、符合要求返回返回 isEmpty() true? //因为这里是收集异常信息啊,没有异常表示输入的符合要求! return mValidationErrors.isEmpty(); } //重点追第九点。}
(3)PasswordMetrics.java
framework/base/core/java/android/app/admin/PasswordMetrics.java
这个类主要作用是: 密码复杂度量化评估 。
import static com.android.internal.widget.LockPatternUtils.MIN_LOCK_PASSWORD_SIZE; //关键哦public final class PasswordMetrics implements Parcelable { private static final String TAG = \"PasswordMetrics\"; ... //1、这里主要就是收集一个错误信息的列表并返回public static List validatePassword( PasswordMetrics adminMetrics, int minComplexity, boolean isPin, byte[] password) { if (hasInvalidCharacters(password)) { //2、非法字符 return Collections.singletonList( new PasswordValidationError(CONTAINS_INVALID_CHARACTERS, 0)); } final PasswordMetrics enteredMetrics = computeForPasswordOrPin(password, isPin); return validatePasswordMetrics(adminMetrics, minComplexity, enteredMetrics); } /** * Validates password metrics against minimum metrics and complexity * * @param adminMetrics - minimum metrics to satisfy admin requirements. * @param minComplexity - minimum complexity imposed by the requester. //3、最短要求 * @param actualMetrics - metrics for password to validate. * @return a list of password validation errors. An empty list means the password is OK. //4、如果列表为空,表示就是输入符合要求 * * TODO: move to PasswordPolicy */ public static List validatePasswordMetrics( PasswordMetrics adminMetrics, int minComplexity, PasswordMetrics actualMetrics) { final ComplexityBucket bucket = ComplexityBucket.forComplexity(minComplexity); // Make sure credential type is satisfactory. // TODO: stop relying on credential type ordering. if (actualMetrics.credType < adminMetrics.credType || !bucket.allowsCredType(actualMetrics.credType)) { return Collections.singletonList(new PasswordValidationError(WEAK_CREDENTIAL_TYPE, 0)); } ... //5、创建错误列表集 final ArrayList result = new ArrayList(); if (actualMetrics.length > MAX_PASSWORD_LENGTH) { result.add(new PasswordValidationError(TOO_LONG, MAX_PASSWORD_LENGTH)); } final PasswordMetrics minMetrics = applyComplexity(adminMetrics, actualMetrics.credType == CREDENTIAL_TYPE_PIN, bucket); // Clamp required length between maximum and minimum valid values. //设置字符串最大长度和最小长度的要求,MAX_PASSWORD_LENGTH =16 //6、MIN_LOCK_PASSWORD_SIZE = 4 ,这个就是我们需要修改的默认值 minMetrics.length = Math.min(MAX_PASSWORD_LENGTH, Math.max(minMetrics.length, MIN_LOCK_PASSWORD_SIZE)); minMetrics.removeOverlapping();//7、字符串长度对比 comparePasswordMetrics(minMetrics, bucket, actualMetrics, result); return result; }}
从上面MIN_LOCK_PASSWORD_SIZE 导入的位置,就可以确定最小长度的定义的代码在 LockPatternUtils
(4)LockPatternUtils.java
LockPatternUtils
是 Android 系统中负责管理锁屏安全相关功能的核心工具类;
主要处理图案锁、PIN 码、密码等锁屏方式的验证、存储、设置及状态管理;
是连接锁屏界面与系统安全策略的关键组件。
framework\\base\\core\\java\\com\\android\\internal\\widget\\LockPatternUtils.java
/** * Utilities for the lock pattern and its settings. */public class LockPatternUtils { private static final String TAG = \"LockPatternUtils\"; private static final boolean FRP_CREDENTIAL_ENABLED = true; //定义最小锁屏密码的地方 /** * The minimum number of dots in a valid pattern. */ public static final int MIN_LOCK_PATTERN_SIZE = 4; /** * The minimum size of a valid password. */ public static final int MIN_LOCK_PASSWORD_SIZE = 4; /** * The minimum number of dots the user must include in a wrong pattern attempt for it to be * counted. */ public static final int MIN_PATTERN_REGISTER_FAIL = MIN_LOCK_PATTERN_SIZE;}
一顿分析后,最后修改这里就OK了。
三、其他
1、修改Android14 锁屏密码修改为至少6位分析实现代码小结
具体分析过程是从Settings应用一路分析到framework 的LockPatternUtils.java
最后把下面这两个地方修改为6 就可以了。
framework\\base\\core\\java\\com\\android\\internal\\widget\\LockPatternUtils.java /** * The minimum number of dots in a valid pattern. */ public static final int MIN_LOCK_PATTERN_SIZE = 4; /** * The minimum size of a valid password. */ public static final int MIN_LOCK_PASSWORD_SIZE = 4;
2、只是把4修改成6,Settings中显示的锁屏字符串提示需要修改吗?
其实不用修改,至于为啥?
有兴趣的可以自行看看Settings中判断messageh和PasswordMetrics.comparePasswordMetrics提示字符串的地方。
修改前后效果对比:
pin码效果:
密码设置和这个差不多,就不展示了。
图案锁屏设置效果:
系统代码已经有完善判断,不需要再额外适配修改Settings res字符串。