· 5 years ago · Dec 06, 2019, 08:20 PM
1package com.example.fingerfinal;
2
3import android.app.KeyguardManager;
4import android.content.Intent;
5import android.content.SharedPreferences;
6import android.hardware.fingerprint.FingerprintManager;
7import android.os.Build;
8import android.os.Bundle;
9import android.security.keystore.KeyGenParameterSpec;
10import android.security.keystore.KeyProperties;
11import android.util.Log;
12import android.view.View;
13import android.widget.Button;
14import android.widget.ImageView;
15import android.widget.TextView;
16import android.widget.Toast;
17
18import androidx.annotation.NonNull;
19import androidx.appcompat.app.AppCompatActivity;
20import androidx.biometric.BiometricManager;
21import androidx.biometric.BiometricPrompt;
22import androidx.core.content.ContextCompat;
23
24import java.io.IOException;
25import java.security.InvalidAlgorithmParameterException;
26import java.security.InvalidKeyException;
27import java.security.KeyStore;
28import java.security.KeyStoreException;
29import java.security.NoSuchAlgorithmException;
30import java.security.NoSuchProviderException;
31import java.security.UnrecoverableKeyException;
32import java.security.cert.CertificateException;
33import java.util.Base64;
34import java.util.concurrent.Executor;
35
36import javax.crypto.BadPaddingException;
37import javax.crypto.Cipher;
38import javax.crypto.IllegalBlockSizeException;
39import javax.crypto.KeyGenerator;
40import javax.crypto.NoSuchPaddingException;
41import javax.crypto.SecretKey;
42import javax.crypto.spec.IvParameterSpec;
43
44import static com.example.fingerfinal.methods.bytetoString;
45import static com.example.fingerfinal.methods.generateSalt;
46
47public class MainActivity extends AppCompatActivity {
48
49
50 private TextView mHeadingLabel;
51 private ImageView mFingerprintImage;
52 private TextView mParaLabel;
53
54 private FingerprintManager fingerprintManager;
55 private KeyguardManager keyguardManager;
56
57
58 TextView text;
59 Button button;
60 String ALIAS = "bsmkey";
61 private BiometricPrompt biometricPrompt;
62 private BiometricPrompt.PromptInfo promptInfo;
63 Cipher cipher;
64 SecretKey secretKey;
65 byte[] iv;
66 String passString;
67 SharedPreferences FingerContent = getSharedPreferences("keys", 0);
68 String key = FingerContent.getString("firstkey", "");
69 @Override
70 protected void onCreate(Bundle savedInstanceState) {
71 super.onCreate(savedInstanceState);
72 setContentView(R.layout.activity_main);
73 final Executor executor = ContextCompat.getMainExecutor(this);
74 BiometricManager biometricManager = BiometricManager.from(this);
75 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
76 switch (biometricManager.canAuthenticate()) {
77 case BiometricManager.BIOMETRIC_SUCCESS:
78 Log.d("MY_APP_TAG", "App can authenticate using biometrics.");
79 break;
80 case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
81 Log.e("MY_APP_TAG", "No biometric features available on this device.");
82 break;
83 case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
84 Log.e("MY_APP_TAG", "Biometric features are currently unavailable.");
85 break;
86 case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
87 Log.e("MY_APP_TAG", "The user hasn't associated " +
88 "any biometric credentials with their account.");
89 break;
90 }
91 }
92
93 promptInfo = new BiometricPrompt.PromptInfo.Builder()
94 .setTitle("Biometric login for my app")
95 .setSubtitle("Log in using your biometric credential")
96 .setNegativeButtonText("Cofnij")
97 .build();
98
99 if(key == ""){
100 String pass = bytetoString(generateSalt()); //klucz do szyfrowania
101 SharedPreferences saltContent = getSharedPreferences("Salt", 0);
102 String salt = saltContent.getString("salt", "");
103 try {
104 generateSecretKey(new KeyGenParameterSpec.Builder(
105 ALIAS,
106 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
107 .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
108 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
109 .setUserAuthenticationRequired(true)
110 // Invalidate the keys if the user has registered a new biometric
111 // credential, such as a new fingerprint. Can call this method only
112 // on Android 7.0 (API level 24) or higher. The variable
113 // "invalidatedByBiometricEnrollment" is true by default.
114 .build());
115 } catch (NoSuchProviderException e) {
116 e.printStackTrace();
117 } catch (NoSuchAlgorithmException e) {
118 e.printStackTrace();
119 }
120
121 biometricPrompt = new BiometricPrompt(MainActivity.this,
122 executor, new BiometricPrompt.AuthenticationCallback() {
123 @Override
124 public void onAuthenticationError(int errorCode,
125 @NonNull CharSequence errString) {
126 super.onAuthenticationError(errorCode, errString);
127 Toast.makeText(getApplicationContext(),
128 "Authentication error: " + errString, Toast.LENGTH_SHORT)
129 .show();
130 }
131
132 @Override
133 public void onAuthenticationSucceeded(
134 @NonNull BiometricPrompt.AuthenticationResult result) {
135 try {
136 byte[] encrypted = result.getCryptoObject().getCipher().doFinal(key.getBytes());
137 SharedPreferences prefs = getSharedPreferences("keys", 0);
138 SharedPreferences.Editor editor = getSharedPreferences("keys", 0).edit();
139 editor.putString("firstkey", Base64.getEncoder().encodeToString(encrypted));
140 editor.apply();
141
142 } catch (BadPaddingException e) {
143 e.printStackTrace();
144 } catch (IllegalBlockSizeException e) {
145 e.printStackTrace();
146 }
147
148 }
149
150
151 @Override
152 public void onAuthenticationFailed() {
153 super.onAuthenticationFailed();
154 Toast.makeText(getApplicationContext(), "Authentication failed",
155 Toast.LENGTH_SHORT)
156 .show();
157 }
158 });
159 }
160
161 biometricPrompt = new BiometricPrompt(MainActivity.this,
162 executor, new BiometricPrompt.AuthenticationCallback() {
163 @Override
164 public void onAuthenticationError(int errorCode,
165 @NonNull CharSequence errString) {
166 super.onAuthenticationError(errorCode, errString);
167 Toast.makeText(getApplicationContext(),
168 "Authentication error: " + errString, Toast.LENGTH_SHORT)
169 .show();
170 }
171
172 @Override
173 public void onAuthenticationSucceeded(
174 @NonNull BiometricPrompt.AuthenticationResult result) {
175 SharedPreferences prefs = getSharedPreferences("KEYS", 0);
176 String encrypteds = prefs.getString("pass", "");
177 byte[] encrypted = Base64.getDecoder().decode(encrypteds);
178 try {
179 byte[] password = result.getCryptoObject().getCipher().doFinal(encrypted);
180 Log.d("HASLO", new String(password));
181 Intent i = new Intent(getApplicationContext(), MainActivity.class);
182 i.putExtra("pass", new String(password));
183 startActivity(i);
184 finish();
185 } catch (BadPaddingException e) {
186 e.printStackTrace();
187 } catch (IllegalBlockSizeException e) {
188 e.printStackTrace();
189 }
190 }
191 @Override
192 public void onAuthenticationFailed() {
193 super.onAuthenticationFailed();
194 Toast.makeText(getApplicationContext(), "Authentication failed",
195 Toast.LENGTH_SHORT)
196 .show();
197 }
198 });
199 button.setOnClickListener(view -> {
200 passString = pass.getText().toString();
201 try {
202 cipher = getCipher();
203 secretKey = getSecretKey();
204 cipher.init(Cipher.ENCRYPT_MODE, secretKey);
205 iv = cipher.getIV();
206 SharedPreferences prefs = getSharedPreferences("KEYS", 0);
207 SharedPreferences.Editor editor = getSharedPreferences("KEYS", Context.MODE_PRIVATE).edit();
208 String ivs = Base64.getEncoder().encodeToString(iv);
209 editor.putString("iv", ivs);
210 editor.apply();
211 biometricPrompt.authenticate(promptInfo,
212 new BiometricPrompt.CryptoObject(cipher));
213 } catch (NoSuchPaddingException e) {
214 e.printStackTrace();
215 } catch (NoSuchAlgorithmException e) {
216 e.printStackTrace();
217 } catch (IOException e) {
218 e.printStackTrace();
219 } catch (CertificateException e) {
220 e.printStackTrace();
221 } catch (UnrecoverableKeyException e) {
222 e.printStackTrace();
223 } catch (InvalidKeyException e) {
224 e.printStackTrace();
225 } catch (KeyStoreException e) {
226 e.printStackTrace();
227 }
228
229
230
231
232
233 });
234 }
235
236 private void generateSecretKey (KeyGenParameterSpec keyGenParameterSpec) throws
237 NoSuchProviderException, NoSuchAlgorithmException {
238 KeyGenerator keyGenerator = KeyGenerator.getInstance(
239 KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
240 try {
241 keyGenerator.init(keyGenParameterSpec);
242 keyGenerator.generateKey();
243 } catch (InvalidAlgorithmParameterException e) {
244 e.printStackTrace();
245 }
246
247 }
248
249 private SecretKey getSecretKey () throws
250 KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException
251 {
252 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
253
254 // Before the keystore can be accessed, it must be loaded.
255 keyStore.load(null);
256 return ((SecretKey) keyStore.getKey(ALIAS, null));
257 }
258
259 private Cipher getCipher () throws NoSuchPaddingException, NoSuchAlgorithmException {
260 return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
261 + KeyProperties.BLOCK_MODE_CBC + "/"
262 + KeyProperties.ENCRYPTION_PADDING_PKCS7);
263 }
264}