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; // 原值为4
public 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; //修改为6private static final int MAX_PIN_LENGTH = 8;}
测试了一下不行,搜索后才发现Icc是sim卡管理作用的,和锁屏没啥关系。
所以只能一步步分析了。
(1)找到界面对应的代码
正常界面如下:
Settings应用代码,res\zh-rCh文件夹找到字符串:
<string name="lockpassword_pin_too_short_autoConfirm_extra_message" msgid="3271351502900762571">"{count,plural, =1{PIN 码必须至少包含 # 位数,不过为提高安全性,建议使用 {minAutoConfirmLen} 位数的 PIN 码}other{PIN 码必须至少为 # 位数,不过为提高安全性,建议使用 {minAutoConfirmLen} 位数的 PIN 码}}"</string>
找到 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、锁屏相关的布局@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.choose_lock_password, container, false);}}//2、这里是收集各种输入异常的集合String[] convertErrorCodeToMessages() {List<String> 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<String, Object> arguments = new HashMap<>();arguments.put("count", error.requirement); //5、这里应该是4 !arguments.put("minAutoConfirmLen", MIN_AUTO_PIN_REQUIREMENT_LENGTH); // 6、这里是数值 6message = 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.validatePasswordmValidationErrors = 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<PasswordValidationError> 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<PasswordValidationError> 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<PasswordValidationError> 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字符串。