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; // 原值为4

frameworks/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; //修改为6
    private 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、锁屏相关的布局
        @Override
        public 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、这里是数值 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<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字符串。

相关推荐
云祺vinchin1 小时前
云祺容灾备份系统阿里云对象存储备份与恢复实操手册
网络·安全·数据安全
知孤云出岫1 小时前
网络安全渗透攻击案例实战:某公司内网为目标的渗透测试全过程
安全·web安全
mobsmobs2 小时前
Flutter开发环境搭建与工具链
android·flutter·ios·android studio·xcode
CheungChunChiu2 小时前
深入理解 eMMC RPMB 与 OP-TEE 在 Linux 系统中的应用开发
android·linux·运维·服务器·op-tee
onthewaying3 小时前
CameraX:Android相机开发的现代化解决方案
android
ifengouy3 小时前
Android中compileSdk,minSdk,targetSdk的含义和区别
android
星空梦想plus3 小时前
Android Camera openCamera
android·相机
心 一3 小时前
Linux服务器安全自动化审计实战:一键扫描账户/网络/进程/计划任务风险(附开源脚本)
linux·服务器·安全
求知摆渡3 小时前
「误报木马」:一次安全告警的复盘与思考
运维·后端·安全
德迅云安全-如意3 小时前
关于网络安全等级保护的那些事
网络·安全·web安全