package com.marshalchen.common.uimodule.passcodelock; import android.app.Activity; import android.app.Application; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Base64; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.util.Arrays; import java.util.Date; public class DefaultAppLock extends AbstractAppLock { private Application currentApp; //Keep a reference to the app that invoked the locker private SharedPreferences settings; private Date lostFocusDate; //Add back-compatibility private static final String OLD_PASSWORD_SALT = "sadasauidhsuyeuihdahdiauhs"; private static final String OLD_APP_LOCK_PASSWORD_PREF_KEY = "wp_app_lock_password_key"; private static final String PASSWORD_PREFERENCE_KEY="passcode_lock_prefs_password_key"; private static final String PASSWORD_SALT="11-maggio-2014-osvaldo-al-49novesimo!"; private static final String PASSWORD_ENC_SECRET="5-maggio-2002-Karel-Poborsky"; public DefaultAppLock(Application currentApp) { super(); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(currentApp); this.settings = settings; this.currentApp = currentApp; } public void enable(){ if (android.os.Build.VERSION.SDK_INT < 14) return; if( isPasswordLocked() ) { currentApp.unregisterActivityLifecycleCallbacks(this); currentApp.registerActivityLifecycleCallbacks(this); } } public void disable( ){ if (android.os.Build.VERSION.SDK_INT < 14) return; currentApp.unregisterActivityLifecycleCallbacks(this); } public void forcePasswordLock(){ lostFocusDate = null; } public boolean verifyPassword( String password ){ String storedPassword = ""; if (settings.contains(OLD_APP_LOCK_PASSWORD_PREF_KEY)) { //add back-compatibility //Check if the old value is available storedPassword = settings.getString(OLD_APP_LOCK_PASSWORD_PREF_KEY, ""); password = OLD_PASSWORD_SALT + password + OLD_PASSWORD_SALT; password = StringUtils.getMd5Hash(password); } else if (settings.contains(PASSWORD_PREFERENCE_KEY)) { //read the password from the new key storedPassword = settings.getString(PASSWORD_PREFERENCE_KEY, ""); storedPassword = decryptPassword(storedPassword); password = PASSWORD_SALT + password + PASSWORD_SALT; } if( password.equalsIgnoreCase(storedPassword) ) { lostFocusDate = new Date(); return true; } else { return false; } } public boolean setPassword(String password){ SharedPreferences.Editor editor = settings.edit(); if(password == null) { editor.remove(OLD_APP_LOCK_PASSWORD_PREF_KEY); editor.remove(PASSWORD_PREFERENCE_KEY); editor.commit(); this.disable(); } else { password = PASSWORD_SALT + password + PASSWORD_SALT; password = encryptPassword(password); editor.putString(PASSWORD_PREFERENCE_KEY, password); editor.remove(OLD_APP_LOCK_PASSWORD_PREF_KEY); editor.commit(); this.enable(); } return true; } //Check if we need to show the lock screen at startup public boolean isPasswordLocked(){ if (settings.contains(OLD_APP_LOCK_PASSWORD_PREF_KEY)) //Check if the old value is available return true; if (settings.contains(PASSWORD_PREFERENCE_KEY)) return true; return false; } private String encryptPassword(String clearText) { try { DESKeySpec keySpec = new DESKeySpec( PASSWORD_ENC_SECRET.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(keySpec); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key); String encrypedPwd = Base64.encodeToString(cipher.doFinal(clearText .getBytes("UTF-8")), Base64.DEFAULT); return encrypedPwd; } catch (Exception e) { } return clearText; } private String decryptPassword(String encryptedPwd) { try { DESKeySpec keySpec = new DESKeySpec(PASSWORD_ENC_SECRET.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(keySpec); byte[] encryptedWithoutB64 = Base64.decode(encryptedPwd, Base64.DEFAULT); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] plainTextPwdBytes = cipher.doFinal(encryptedWithoutB64); return new String(plainTextPwdBytes); } catch (Exception e) { } return encryptedPwd; } private boolean mustShowUnlockSceen() { if( isPasswordLocked() == false) return false; if( lostFocusDate == null ) return true; //first startup or when we forced to show the password int currentTimeOut = lockTimeOut; //get a reference to the current password timeout and reset it to default lockTimeOut = DEFAULT_TIMEOUT; Date now = new Date(); long now_ms = now.getTime(); long lost_focus_ms = lostFocusDate.getTime(); int secondsPassed = (int) (now_ms - lost_focus_ms)/(1000); secondsPassed = Math.abs(secondsPassed); //Make sure changing the clock on the device to a time in the past doesn't by-pass PIN Lock if (secondsPassed >= currentTimeOut) { lostFocusDate = null; return true; } return false; } @Override public void onActivityPaused(Activity arg0) { if( arg0.getClass() == PasscodeUnlockActivity.class ) return; if( ( this.appLockDisabledActivities != null ) && Arrays.asList(this.appLockDisabledActivities).contains( arg0.getClass().getName() ) ) return; lostFocusDate = new Date(); } @Override public void onActivityResumed(Activity arg0) { if( arg0.getClass() == PasscodeUnlockActivity.class ) return; if( ( this.appLockDisabledActivities != null ) && Arrays.asList(this.appLockDisabledActivities).contains( arg0.getClass().getName() ) ) return; if(mustShowUnlockSceen()) { //uhhh ohhh! Intent i = new Intent(arg0.getApplicationContext(), PasscodeUnlockActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); arg0.getApplication().startActivity(i); return; } } @Override public void onActivityCreated(Activity arg0, Bundle arg1) { } @Override public void onActivityDestroyed(Activity arg0) { } @Override public void onActivitySaveInstanceState(Activity arg0, Bundle arg1) { } @Override public void onActivityStarted(Activity arg0) { } @Override public void onActivityStopped(Activity arg0) { } }