First step

This commit is contained in:
Tanguy Herbron 2018-02-28 12:31:14 +01:00
parent 9cacb7a380
commit c199732fa4
7 changed files with 199 additions and 1 deletions

View File

@ -4,7 +4,7 @@ android {
compileSdkVersion 26 compileSdkVersion 26
defaultConfig { defaultConfig {
applicationId "com.nauk.coinfolio" applicationId "com.nauk.coinfolio"
minSdkVersion 21 minSdkVersion 23
targetSdkVersion 26 targetSdkVersion 26
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
@ -41,6 +41,7 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-jackson:2.2.0' implementation 'com.squareup.retrofit2:converter-jackson:2.2.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
implementation 'org.apache.commons:commons-lang3:3.6' implementation 'org.apache.commons:commons-lang3:3.6'
implementation 'com.mattprecious.swirl:swirl:1.1.0'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

View File

@ -2,7 +2,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nauk.coinfolio"> package="com.nauk.coinfolio">
<uses-feature android:name="android.hardware.fingerprint"
android:required="false"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<application <application
android:allowBackup="true" android:allowBackup="true"

View File

@ -1,9 +1,13 @@
package com.nauk.coinfolio.Activities; package com.nauk.coinfolio.Activities;
import android.Manifest;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.KeyguardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.hardware.fingerprint.FingerprintManager;
import android.media.Ringtone; import android.media.Ringtone;
import android.media.RingtoneManager; import android.media.RingtoneManager;
import android.net.Uri; import android.net.Uri;
@ -15,14 +19,35 @@ import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.RingtonePreference; import android.preference.RingtonePreference;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.nauk.coinfolio.FingerprintHelper.FingerprintHandler;
import com.nauk.coinfolio.R; import com.nauk.coinfolio.R;
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 java.util.List; import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
/** /**
* A {@link PreferenceActivity} that presents a set of application settings. On * A {@link PreferenceActivity} that presents a set of application settings. On
* handset devices, settings are presented as a single list. On tablets, * handset devices, settings are presented as a single list. On tablets,
@ -36,6 +61,14 @@ import java.util.List;
*/ */
public class SettingsActivity extends AppCompatPreferenceActivity { public class SettingsActivity extends AppCompatPreferenceActivity {
private static final String KEY_NAME = "NAUKEY";
private Cipher cipher;
private KeyStore keyStore;
private KeyGenerator keyGenerator;
private FingerprintManager.CryptoObject cryptoObject;
private FingerprintManager fingerprintManager;
private KeyguardManager keyguardManager;
/** /**
* A preference value change listener that updates the preference's summary * A preference value change listener that updates the preference's summary
* to reflect its new value. * to reflect its new value.
@ -131,6 +164,105 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setupActionBar(); setupActionBar();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
if(!fingerprintManager.isHardwareDetected())
{
findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
{
findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(!fingerprintManager.hasEnrolledFingerprints())
{
findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(!keyguardManager.isKeyguardSecure())
{
findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
else
{
try {
generateKey();
} catch (FingerprintException e) {
e.printStackTrace();
}
if(initCipher())
{
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this);
helper.startAuth(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 e) {
e.printStackTrace();
throw new FingerprintException(e);
}
}
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);
}
} }
/** /**

View File

@ -0,0 +1,34 @@
package com.nauk.coinfolio.FingerprintHelper;
import android.Manifest;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.CancellationSignal;
import android.support.v4.app.ActivityCompat;
/**
* Created by Guitoune on 28/02/2018.
*/
public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {
private CancellationSignal cancellationSignal;
private Context context;
public FingerprintHandler(Context context)
{
this.context = context;
}
public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject)
{
cancellationSignal = new CancellationSignal();
if(ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
{
return;
}
manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);
}
}

View File

@ -0,0 +1,19 @@
<?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:id="@+id/edit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/fingerprint_textview"
android:text="@string/pref_fingerprint"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.mattprecious.swirl.SwirlView
android:layout_width="60dp"
android:layout_height="60dp" />
</LinearLayout>

View File

@ -79,6 +79,9 @@
<string name="pref_title_vibrate">Vibrate</string> <string name="pref_title_vibrate">Vibrate</string>
<!--Fingerprint authentification-->
<string name="fingerprint_verification">Verify your fingerprint</string>
<!--Exchange strings--> <!--Exchange strings-->
<string name="pref_header_exchange">Exchanges settings</string> <string name="pref_header_exchange">Exchanges settings</string>

View File

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:id="@+id/fingerprint_switch"
android:key="enable_fingerprint"
android:title="@string/pref_fingerprint" />
<PreferenceCategory <PreferenceCategory
android:title="@string/pref_title_exchange_hitbtc"> android:title="@string/pref_title_exchange_hitbtc">
<SwitchPreference <SwitchPreference