Commit 6d3302d8 authored by Loris's avatar Loris Committed by Donald

fingerprint security (#434)

feature for #396 #235
parent 43eeb916
......@@ -93,7 +93,7 @@ dependencies {
// rxJava
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
//it is recommended to keep the same version of rxAndroid
implementation 'io.reactivex.rxjava2:rxjava:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.2'
implementation 'com.jakewharton.rxrelay2:rxrelay:2.0.0'
// icons
......@@ -120,7 +120,7 @@ dependencies {
// TODO check them out
implementation 'com.turingtechnologies.materialscrollbar:lib:10.0.3'
implementation 'de.psdev.licensesdialog:licensesdialog:1.8.0'
implementation 'de.psdev.licensesdialog:licensesdialog:1.8.3'
}
Properties props = new Properties()
......
......@@ -13,6 +13,8 @@
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature android:name="android.hardware.fingerprint"
android:required="false"/>
<application
android:allowBackup="true"
......
......@@ -2,6 +2,7 @@ package org.horaapps.leafpic.activities;
import android.content.DialogInterface;
import android.graphics.PorterDuff;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.v7.app.AlertDialog;
......@@ -19,10 +20,13 @@ import com.mikepenz.iconics.view.IconicsImageView;
import com.orhanobut.hawk.Hawk;
import org.horaapps.leafpic.R;
import org.horaapps.leafpic.util.FingerprintHandler;
import org.horaapps.leafpic.util.Security;
import org.horaapps.liz.ThemeHelper;
import org.horaapps.liz.ThemedActivity;
import static android.view.View.GONE;
/**
* Created by dnld on 22/05/16.
*/
......@@ -34,19 +38,36 @@ public class SecurityActivity extends ThemedActivity {
private SwitchCompat swActiveSecurity;
private SwitchCompat swApplySecurityDelete;
private SwitchCompat swApplySecurityHidden;
private SwitchCompat swFingerPrint;
private LinearLayout llFingerprint;
private FingerprintHandler fingerprintHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(org.horaapps.leafpic.R.layout.activity_security);
llroot = (LinearLayout) findViewById(org.horaapps.leafpic.R.id.root);
toolbar = (Toolbar) findViewById(org.horaapps.leafpic.R.id.toolbar);
swActiveSecurity = (SwitchCompat) findViewById(org.horaapps.leafpic.R.id.active_security_switch);
swApplySecurityDelete = (SwitchCompat) findViewById(org.horaapps.leafpic.R.id.security_body_apply_delete_switch);
swApplySecurityHidden = (SwitchCompat) findViewById(org.horaapps.leafpic.R.id.security_body_apply_hidden_switch);
setContentView(R.layout.activity_security);
llroot = (LinearLayout) findViewById(R.id.root);
toolbar = (Toolbar) findViewById(R.id.toolbar);
swActiveSecurity = (SwitchCompat) findViewById(R.id.active_security_switch);
swApplySecurityDelete = (SwitchCompat) findViewById(R.id.security_body_apply_delete_switch);
swApplySecurityHidden = (SwitchCompat) findViewById(R.id.security_body_apply_hidden_switch);
swFingerPrint = (SwitchCompat) findViewById(R.id.active_security_fingerprint_switch);
llFingerprint = (LinearLayout) findViewById(R.id.ll_active_security_fingerprint);
initUi();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
fingerprintHandler = new FingerprintHandler(this);
if(fingerprintHandler.isFingerprintSupported()){
llFingerprint.setVisibility(View.VISIBLE);
}else{
llFingerprint.setVisibility(View.GONE);
}
}else{
llFingerprint.setVisibility(View.GONE);
}
/** - SWITCHES - **/
/** - ACTIVE SECURITY - **/
swActiveSecurity.setChecked(Security.isPasswordSet(getApplicationContext()));
......@@ -57,7 +78,19 @@ public class SecurityActivity extends ThemedActivity {
swActiveSecurity.setChecked(!swActiveSecurity.isChecked());
setSwitchColor(getAccentColor(), swActiveSecurity);
if (swActiveSecurity.isChecked()) setPasswordDialog();
else Security.clearPassword(getApplicationContext());
else{
Security.clearPassword(getApplicationContext());
swApplySecurityHidden.setChecked(false);
swApplySecurityDelete.setChecked(false);
swFingerPrint.setChecked(false);
Security.setFingerprintUnlock(getApplicationContext(), swFingerPrint.isChecked());
Security.setPasswordOnDelete(getApplicationContext(), swApplySecurityDelete.isChecked());
Security.setPasswordOnHidden(getApplicationContext(), swApplySecurityHidden.isChecked());
setSwitchColor(getAccentColor(), swApplySecurityHidden);
setSwitchColor(getAccentColor(), swApplySecurityDelete);
setSwitchColor(getAccentColor(), swFingerPrint);
}
toggleEnabledChild(swActiveSecurity.isChecked());
}
});
......@@ -85,6 +118,18 @@ public class SecurityActivity extends ThemedActivity {
setSwitchColor(getAccentColor(), swApplySecurityDelete);
}
});
/** - FINGERPRINT - **/
swFingerPrint.setChecked(Hawk.get("fingerprint_security", false));
swFingerPrint.setClickable(false);
findViewById(R.id.ll_active_security_fingerprint).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
swFingerPrint.setChecked(!swFingerPrint.isChecked());
Security.setFingerprintUnlock(getApplicationContext(), swFingerPrint.isChecked());
setSwitchColor(getAccentColor(), swFingerPrint);
}
});
}
private void initUi() {
......@@ -153,16 +198,22 @@ public class SecurityActivity extends ThemedActivity {
private void toggleEnabledChild(boolean enable) {
findViewById(R.id.ll_security_body_apply_hidden).setEnabled(enable);
findViewById(R.id.ll_security_body_apply_delete).setClickable(enable);
findViewById(R.id.ll_active_security_fingerprint).setClickable(enable);
if(enable){
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_hidden_icon)).setColor(getIconColor());
((TextView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_hidden_title)).setTextColor(getTextColor());
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_delete_icon)).setColor(getIconColor());
((TextView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_delete_title)).setTextColor(getTextColor());
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.active_security_fingerprint_icon)).setColor(getIconColor());
((TextView) findViewById(org.horaapps.leafpic.R.id.active_security_fingerprint_item_title)).setTextColor(getTextColor());
} else {
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_hidden_icon)).setColor(getSubTextColor());
((TextView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_hidden_title)).setTextColor(getSubTextColor());
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_delete_icon)).setColor(getSubTextColor());
((TextView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_delete_title)).setTextColor(getSubTextColor());
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.active_security_fingerprint_icon)).setColor(getSubTextColor());
((TextView) findViewById(org.horaapps.leafpic.R.id.active_security_fingerprint_item_title)).setTextColor(getSubTextColor());
}
}
......@@ -174,7 +225,7 @@ public class SecurityActivity extends ThemedActivity {
setRecentApp(getString(R.string.security));
toolbar.setBackgroundColor(getPrimaryColor());
setSwitchColor(getAccentColor(), swActiveSecurity, swApplySecurityHidden, swApplySecurityDelete);
setSwitchColor(getAccentColor(), swActiveSecurity, swApplySecurityHidden, swApplySecurityDelete, swFingerPrint);
toggleEnabledChild(swActiveSecurity.isChecked());
setStatusBarColor();
......@@ -188,6 +239,7 @@ public class SecurityActivity extends ThemedActivity {
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.active_security_icon)).setColor(color);
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_hidden_icon)).setColor(color);
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_delete_icon)).setColor(color);
((IconicsImageView) findViewById(org.horaapps.leafpic.R.id.active_security_fingerprint_icon)).setColor(color);
/** TEXTVIEWS **/
color = getTextColor();
......@@ -195,5 +247,7 @@ public class SecurityActivity extends ThemedActivity {
((TextView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_on)).setTextColor(color);
((TextView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_hidden_title)).setTextColor(color);
((TextView) findViewById(org.horaapps.leafpic.R.id.security_body_apply_delete_title)).setTextColor(color);
((TextView) findViewById(org.horaapps.leafpic.R.id.active_security_fingerprint_item_title)).setTextColor(color);
}
}
......@@ -6,6 +6,7 @@ import android.os.Build;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ScrollView;
......@@ -20,6 +21,7 @@ import org.horaapps.leafpic.settings.ColorsSetting;
import org.horaapps.leafpic.settings.GeneralSetting;
import org.horaapps.leafpic.settings.MapProviderSetting;
import org.horaapps.leafpic.settings.SinglePhotoSetting;
import org.horaapps.leafpic.util.FingerprintHandler;
import org.horaapps.leafpic.util.Security;
import org.horaapps.leafpic.views.SettingWithSwitchView;
import org.horaapps.liz.ColorPalette;
......@@ -130,14 +132,41 @@ public class SettingsActivity extends ThemedActivity {
@OnClick(R.id.ll_security)
public void onSecurityClicked(View view) {
if (Security.isPasswordSet(getApplicationContext())) {
Security.askPassword(SettingsActivity.this, new Security.PasswordInterface() {
@Override
public void onSuccess() {startActivity(new Intent(getApplicationContext(), SecurityActivity.class));}
@Override
public void onError() {Toast.makeText(getApplicationContext(), R.string.wrong_password, Toast.LENGTH_SHORT).show();}
});
} else startActivity(new Intent(getApplicationContext(), SecurityActivity.class));
if (Security.isPasswordSet(getApplicationContext()) && Security.isFingerprintUsed(getApplicationContext()) && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
FingerprintHandler fingerprintHandler = new FingerprintHandler(getApplicationContext());
if (fingerprintHandler.isFingerprintSupported()) {
Security.AskFingerprint askFingerprint = new Security().new AskFingerprint();
askFingerprint.ask(SettingsActivity.this, new Security.FingerprintInterface() {
@Override
public void onSuccess() {
startActivity(new Intent(getApplicationContext(), SecurityActivity.class));
}
@Override
public void onError() {
Toast.makeText(getApplicationContext(), R.string.fingerprint_error, Toast.LENGTH_SHORT).show();
}
@Override
public void onUsePsw() {
askPassword();
}
});
}else {
askPassword();
}
}else if (Security.isPasswordSet(getApplicationContext())) {
askPassword();
}else startActivity(new Intent(getApplicationContext(), SecurityActivity.class));
}
private void askPassword(){
Security.askPassword(SettingsActivity.this, new Security.PasswordInterface() {
@Override
public void onSuccess() {startActivity(new Intent(getApplicationContext(), SecurityActivity.class));}
@Override
public void onError() {Toast.makeText(getApplicationContext(), R.string.wrong_password, Toast.LENGTH_SHORT).show();}
});
}
@OnClick(R.id.ll_primaryColor)
......
package org.horaapps.leafpic.util;
/**
* Created by Loris on 9/9/2017.
*/
import android.Manifest;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.CancellationSignal;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import static android.content.Context.FINGERPRINT_SERVICE;
import static android.content.Context.KEYGUARD_SERVICE;
/**
* Created by francesco on 29/11/16.
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {
private static final String KEY_NAME = "fingerprint_key";
private Cipher cipher;
private KeyStore keyStore;
private KeyGenerator keyGenerator;
private FingerprintManager.CryptoObject cryptoObject;
private FingerprintManager fingerprintManager;
private KeyguardManager keyguardManager;
private Context context;
private boolean fingerprintSupported = true;
private OnFingerprintResult onFingerprintResult;
public FingerprintHandler(Context context) {
this.context = context;
keyguardManager =
(KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);
fingerprintManager =
(FingerprintManager) context.getSystemService(FINGERPRINT_SERVICE);
}
public void setOnFingerprintResult(OnFingerprintResult fingerprintResult) {
this.onFingerprintResult = fingerprintResult;
}
public boolean isFingerprintSupported() {
if (!fingerprintManager.isHardwareDetected()) {
//Toast.makeText(context, "Your device doesn't support fingerprint authentication", Toast.LENGTH_SHORT).show();
fingerprintSupported = false;
}
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
//Toast.makeText(context, "Please enable the fingerprint permission", Toast.LENGTH_SHORT).show();
fingerprintSupported = false;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
//Toast.makeText(context, "No fingerprint configured. Please register at least one fingerprint in your device's Settings", Toast.LENGTH_SHORT).show();
fingerprintSupported = false;
}
if (!keyguardManager.isKeyguardSecure()) {
//Toast.makeText(context, "Please enable lockscreen security in your device's Settings", Toast.LENGTH_SHORT).show();
fingerprintSupported = false;
}
return fingerprintSupported;
}
public void startAuth() {
if (fingerprintSupported) {
try {
generateKey();
} catch (FingerprintException e) {
e.printStackTrace();
}
if (initCipher()) {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(context);
doAuth(fingerprintManager, cryptoObject);
}
}
}
private void generateKey() throws FingerprintException {
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
keyStore.load(null);
keyGenerator.init(new
KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
keyGenerator.generateKey();
} catch (KeyStoreException
| NoSuchAlgorithmException
| NoSuchProviderException
| InvalidAlgorithmParameterException
| CertificateException
| IOException exc) {
exc.printStackTrace();
throw new FingerprintException(exc);
}
}
public boolean initCipher() {
try {
cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException |
NoSuchPaddingException e) {
throw new RuntimeException("Failed to get Cipher", e);
}
try {
keyStore.load(null);
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
null);
cipher.init(Cipher.ENCRYPT_MODE, key);
return true;
} catch (KeyPermanentlyInvalidatedException e) {
return false;
} catch (KeyStoreException | CertificateException
| UnrecoverableKeyException | IOException
| NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Failed to init Cipher", e);
}
}
private class FingerprintException extends Exception {
public FingerprintException(Exception e) {
super(e);
}
}
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
if (onFingerprintResult != null)
onFingerprintResult.onError();
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
super.onAuthenticationHelp(helpCode, helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
if (onFingerprintResult != null)
onFingerprintResult.onSuccess();
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
}
public void doAuth(FingerprintManager manager, FingerprintManager.CryptoObject obj) {
CancellationSignal signal = new CancellationSignal();
try {
manager.authenticate(obj, signal, 0, this, null);
} catch (SecurityException sce) {
}
}
public interface OnFingerprintResult {
void onSuccess();
void onError();
}
}
\ No newline at end of file
......@@ -3,12 +3,15 @@ package org.horaapps.leafpic.util;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.PorterDuff;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.orhanobut.hawk.Hawk;
......@@ -32,6 +35,10 @@ public class Security {
Hawk.put("password_on_hidden", passwordOnHidden);
}
public static void setFingerprintUnlock(Context context, boolean passwordOnHidden) {
Hawk.put("fingerprint_security", passwordOnHidden);
}
public static boolean isPasswordSet(Context context) {
return Hawk.get("password_hash", null) != null;
}
......@@ -40,11 +47,15 @@ public class Security {
return Hawk.get("password_hash", null) != null && Hawk.get("password_on_hidden", false);
}
public static boolean isFingerprintUsed(Context context) {
return Hawk.get("fingerprint_security", false);
}
public static boolean isPasswordOnDelete(Context context) {
return Hawk.get("password_hash", null) != null && Hawk.get("password_on_delete", false);
}
private static boolean checkPassword(Context context, String pass){
private static boolean checkPassword(Context context, String pass) {
return sha256(pass).equals(Hawk.get("password_hash", null));
}
......@@ -57,7 +68,13 @@ public class Security {
}
public static void askPassword(final ThemedActivity activity, final PasswordInterface passwordInterface) {
AlertDialog.Builder passwordDialogBuilder = new AlertDialog.Builder (activity, activity.getDialogStyle());
AlertDialog.Builder passwordDialogBuilder = new AlertDialog.Builder(activity, activity.getDialogStyle());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
FingerprintHandler fingerprintHandler = new FingerprintHandler(activity);
} else {
}
final View PasswordDialogLayout = activity.getLayoutInflater().inflate(org.horaapps.leafpic.R.layout.dialog_password, null);
final TextView passwordDialogTitle = (TextView) PasswordDialogLayout.findViewById(org.horaapps.leafpic.R.id.password_dialog_title);
......@@ -70,8 +87,6 @@ public class Security {
editTextPassword.getBackground().mutate().setColorFilter(activity.getTextColor(), PorterDuff.Mode.SRC_ATOP);
editTextPassword.setTextColor(activity.getTextColor());
//Finger Print
//if(FingerPrint.checkFinger(activity))
passwordDialogBuilder.setView(PasswordDialogLayout);
......@@ -97,7 +112,7 @@ public class Security {
.OnClickListener() {
@Override
public void onClick(View v) {
if (checkPassword(activity, editTextPassword.getText().toString())){
if (checkPassword(activity, editTextPassword.getText().toString())) {
hideKeyboard(activity, editTextPassword.getWindowToken());
passwordDialog.dismiss();
passwordInterface.onSuccess();
......@@ -110,9 +125,72 @@ public class Security {
});
}
@RequiresApi(api = Build.VERSION_CODES.M)
public class AskFingerprint implements FingerprintHandler.OnFingerprintResult {
AlertDialog passwordDialog;
FingerprintInterface fingerprintInterface;
public AskFingerprint() {
}
public void ask(final ThemedActivity activity, final FingerprintInterface fingerprintInterface) {
AlertDialog.Builder passwordDialogBuilder = new AlertDialog.Builder(activity, activity.getDialogStyle());
this.fingerprintInterface = fingerprintInterface;
FingerprintHandler fingerprintHandler = new FingerprintHandler(activity);
fingerprintHandler.setOnFingerprintResult(this);
fingerprintHandler.startAuth();
final View PasswordDialogLayout = activity.getLayoutInflater().inflate(R.layout.dialog_fingerprint, null);
final TextView passwordDialogTitle = (TextView) PasswordDialogLayout.findViewById(org.horaapps.leafpic.R.id.password_dialog_title);
final CardView passwordDialogCard = (CardView) PasswordDialogLayout.findViewById(org.horaapps.leafpic.R.id.password_dialog_card);
final LinearLayout llUsePsw = (LinearLayout) PasswordDialogLayout.findViewById(R.id.ll_use_psw);
final ThemedIcon fingerprintIcon = (ThemedIcon) PasswordDialogLayout.findViewById(R.id.fingerprint_icon);
fingerprintIcon.setColor(activity.getIconColor());
passwordDialogTitle.setBackgroundColor(activity.getPrimaryColor());
passwordDialogCard.setBackgroundColor(activity.getCardBackgroundColor());
passwordDialogBuilder.setView(PasswordDialogLayout);
passwordDialogBuilder.setNegativeButton(activity.getString(R.string.cancel).toUpperCase(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// NOTE: set this empty, later will be overwrite to avoid the dismiss
}
});
passwordDialog = passwordDialogBuilder.create();
passwordDialog.show();
llUsePsw.setOnClickListener(view -> {
passwordDialog.dismiss();
fingerprintInterface.onUsePsw();
});
}
@Override
public void onSuccess() {
passwordDialog.dismiss();
fingerprintInterface.onSuccess();
}
@Override
public void onError() {
fingerprintInterface.onError();
}
}
private static void showKeyboard(Context context) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
private static void hideKeyboard(Context context, IBinder token) {
......@@ -121,7 +199,7 @@ public class Security {
}
private static String sha256(String base) {
try{
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(base.getBytes("UTF-8"));
StringBuilder hexString = new StringBuilder();
......@@ -131,11 +209,23 @@ public class Security {
hexString.append(hex);
}
return hexString.toString();
} catch(Exception ex){ throw new RuntimeException(ex); }
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public interface PasswordInterface {
void onSuccess();
void onError();
}
public interface FingerprintInterface {
void onSuccess();
void onError();
void onUsePsw();
}
}
......@@ -66,7 +66,7 @@
</RelativeLayout>
</LinearLayout>
<!--USE FINGERPRINT-->
<!--
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_active_security_fingerprint"
......@@ -76,8 +76,8 @@
>
<com.mikepenz.iconics.view.IconicsImageView
android:id="@+id/active_security_fingerprint_icon"
android:layout_width="@dimen/20dp"
android:layout_height="@dimen/20dp"
android:layout_width="@dimen/icon_width_height"
android:layout_height="@dimen/icon_width_height"
android:layout_gravity="center_vertical"
app:iiv_icon="gmd-fingerprint"
android:layout_margin="@dimen/big_spacing"
......@@ -114,7 +114,6 @@
/>
</RelativeLayout>
</LinearLayout>
-->
<!--BODY-->
<LinearLayout
android:id="@+id/ll_security_dialog_body"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:id="@+id/password_dialog_card"