szyrowanie działa wstepnie
This commit is contained in:
parent
15ae064622
commit
2736b3df36
@ -8,7 +8,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.bsm_fingerptint_tutorial"
|
||||
minSdk 24
|
||||
minSdk 26
|
||||
targetSdk 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
@ -71,18 +71,6 @@ public class MainActivity extends AppCompatActivity {
|
||||
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
|
||||
super.onAuthenticationSucceeded(result);
|
||||
|
||||
String plaintext = "Tekst do zaszyforwania";
|
||||
byte[] encryptedInfo;
|
||||
|
||||
try {
|
||||
encryptedInfo = result.getCryptoObject().getCipher().doFinal(
|
||||
plaintext.getBytes(Charset.defaultCharset()));
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Log.d("MY_LOGS", "Success! Encrypted txt: " + Arrays.toString(encryptedInfo));
|
||||
|
||||
Toast.makeText(getApplicationContext(),"Authentication succeeded!", Toast.LENGTH_SHORT).show();
|
||||
|
||||
Intent intent = new Intent(getApplicationContext(), NotepadActivity.class);
|
||||
@ -104,54 +92,13 @@ public class MainActivity extends AppCompatActivity {
|
||||
.setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG)
|
||||
.build();
|
||||
|
||||
|
||||
try {
|
||||
generateSecretKey(new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
|
||||
.setUserAuthenticationRequired(true)
|
||||
.setInvalidatedByBiometricEnrollment(true)
|
||||
.build()
|
||||
);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
btnLogIn.setOnClickListener(view -> {
|
||||
try {
|
||||
Cipher cipher = getCipher();
|
||||
SecretKey secretKey = getSecretKey();
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
biometricPrompt.authenticate(promptInfo);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void generateSecretKey(KeyGenParameterSpec keyGenParameterSpec) throws GeneralSecurityException {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", "AndroidKeyStore");
|
||||
keyGenerator.init(keyGenParameterSpec);
|
||||
keyGenerator.generateKey();
|
||||
}
|
||||
|
||||
private SecretKey getSecretKey() throws GeneralSecurityException, IOException {
|
||||
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
|
||||
|
||||
keyStore.load(null);
|
||||
return ((SecretKey)keyStore.getKey(KEY_NAME, null));
|
||||
}
|
||||
|
||||
private Cipher getCipher() throws GeneralSecurityException{
|
||||
return Cipher.getInstance("AES/CBC/PKCS7Padding");
|
||||
//KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,12 +2,15 @@ package com.example.bsm_fingerptint_tutorial;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.biometric.BiometricPrompt;
|
||||
import androidx.lifecycle.LifecycleCoroutineScope;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.security.keystore.KeyGenParameterSpec;
|
||||
import android.security.keystore.KeyProperties;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@ -17,16 +20,31 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
public class NotepadActivity extends AppCompatActivity {
|
||||
|
||||
private List<Note> noteList;
|
||||
private LinearLayout notesContainer;
|
||||
private static final String SHARED_NAME_NOTES = "Notatki";
|
||||
|
||||
private static final String KEY_NAME = "nazwaKluczaa";
|
||||
|
||||
|
||||
|
||||
Button buttonLogout, buttonAddNote;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -36,7 +54,11 @@ public class NotepadActivity extends AppCompatActivity {
|
||||
noteList = new ArrayList<>();
|
||||
notesContainer = findViewById(R.id.notes_container);
|
||||
|
||||
loadNotesFromPreferencesToList();
|
||||
try {
|
||||
loadNotesFromPreferencesToList();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
displayNotes();
|
||||
|
||||
buttonLogout = findViewById(R.id.btn_logout);
|
||||
@ -75,7 +97,13 @@ public class NotepadActivity extends AppCompatActivity {
|
||||
|
||||
noteList.add(note);
|
||||
|
||||
saveNotesToPreferences("add");
|
||||
try {
|
||||
saveNotesToPreferences("add");
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
createNoteView(note);
|
||||
Toast.makeText(NotepadActivity.this, "Note saved!", Toast.LENGTH_SHORT).show();
|
||||
@ -116,7 +144,13 @@ public class NotepadActivity extends AppCompatActivity {
|
||||
noteList.add(note);
|
||||
createNoteView(note);
|
||||
|
||||
saveNotesToPreferences("add");
|
||||
try {
|
||||
saveNotesToPreferences("add");
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}else {
|
||||
Toast.makeText(NotepadActivity.this, "Enter title and content!", Toast.LENGTH_SHORT).show();
|
||||
@ -130,44 +164,92 @@ public class NotepadActivity extends AppCompatActivity {
|
||||
alertDialog.show();
|
||||
}
|
||||
|
||||
private void saveNotesToPreferences(String mode){
|
||||
private void saveNotesToPreferences(String mode) throws GeneralSecurityException, IOException {
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_NOTES, MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
|
||||
if (mode.equals("del")){
|
||||
int noteCount = sharedPreferences.getInt("_notecount_", 0);
|
||||
for(int i=0; i<noteCount; i++){
|
||||
editor.remove(i + "_title_");
|
||||
editor.remove(i + "_content_");
|
||||
|
||||
if (mode.equals("del")){
|
||||
int noteCount = sharedPreferences.getInt("_notecount_", 0);
|
||||
for(int i=0; i<noteCount; i++){
|
||||
editor.remove(i + "_title_");
|
||||
editor.remove(i + "_content_");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.putInt("_notecount_", noteList.size());
|
||||
for(int i=0; i<noteList.size(); i++){
|
||||
Note note = noteList.get(i);
|
||||
editor.putString(i + "_title_", note.getTitle());
|
||||
editor.putString(i + "_content_", note.getContent());
|
||||
}
|
||||
IvParameterSpec iv = UtilsCipher.generateIv();
|
||||
String ivString = ivToString(iv);
|
||||
saveIvStringToShared(ivString);
|
||||
|
||||
SecretKey secretKey = UtilsCipher.generateRandomKey(KEY_NAME);
|
||||
|
||||
|
||||
editor.putInt("_notecount_", noteList.size());
|
||||
for(int i=0; i<noteList.size(); i++){
|
||||
Note note = noteList.get(i);
|
||||
|
||||
String encryptedTitle = UtilsCipher.encrypt("AES/CBC/PKCS7Padding", note.getTitle(), secretKey, iv);
|
||||
String encryptedContent = UtilsCipher.encrypt("AES/CBC/PKCS7Padding", note.getContent(), secretKey, iv);
|
||||
|
||||
editor.putString(i + "_title_", encryptedTitle);
|
||||
editor.putString(i + "_content_", encryptedContent);
|
||||
}
|
||||
|
||||
editor.apply();
|
||||
|
||||
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private void loadNotesFromPreferencesToList(){
|
||||
private void loadNotesFromPreferencesToList() throws Exception {
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_NOTES, MODE_PRIVATE);
|
||||
int noteCount = sharedPreferences.getInt("_notecount_", 0);
|
||||
|
||||
String ivString = getIVStringFromShared();
|
||||
IvParameterSpec iv = stringToIv(ivString);
|
||||
|
||||
SecretKey secretKey = UtilsCipher.retrieveKey(KEY_NAME);
|
||||
|
||||
|
||||
for(int i=0; i<noteCount; i++){
|
||||
String title = sharedPreferences.getString(i + "_title_", "");
|
||||
String content = sharedPreferences.getString(i + "_content_", "");
|
||||
|
||||
String decryptedTitle = UtilsCipher.decrypt("AES/CBC/PKCS7Padding", title, secretKey, iv);
|
||||
String decryptedContent = UtilsCipher.decrypt("AES/CBC/PKCS7Padding", content, secretKey, iv);
|
||||
|
||||
Note note = new Note();
|
||||
note.setTitle(title);
|
||||
note.setContent(content);
|
||||
note.setTitle(decryptedTitle);
|
||||
note.setContent(decryptedContent);
|
||||
|
||||
noteList.add(note);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveIvStringToShared(String ivString){
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_NOTES, MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
|
||||
editor.putString("_iv_", ivString);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private String getIVStringFromShared(){
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_NOTES, MODE_PRIVATE);
|
||||
return sharedPreferences.getString("_iv_", "err");
|
||||
}
|
||||
|
||||
private static IvParameterSpec stringToIv(String ivString) {
|
||||
byte[] ivBytes = Base64.getDecoder().decode(ivString);
|
||||
return new IvParameterSpec(ivBytes);
|
||||
}
|
||||
|
||||
private static String ivToString(IvParameterSpec ivParameterSpec) {
|
||||
byte[] ivBytes = ivParameterSpec.getIV();
|
||||
return Base64.getEncoder().encodeToString(ivBytes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void createNoteView(final Note note){
|
||||
@SuppressLint("InflateParams") View noteView = getLayoutInflater().inflate(R.layout.note_item, null);
|
||||
TextView noteTitleTextView = noteView.findViewById(R.id.note_title_text_view);
|
||||
@ -200,7 +282,13 @@ public class NotepadActivity extends AppCompatActivity {
|
||||
|
||||
private void deleteNoteAndRefresh(Note note){
|
||||
noteList.remove(note);
|
||||
saveNotesToPreferences("del");
|
||||
try {
|
||||
saveNotesToPreferences("del");
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
refreshNotesView();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,91 @@
|
||||
package com.example.bsm_fingerptint_tutorial;
|
||||
|
||||
import android.security.keystore.KeyGenParameterSpec;
|
||||
import android.security.keystore.KeyProperties;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class UtilsCipher {
|
||||
|
||||
public static SecretKey generateRandomKey(String keyAlias) throws NoSuchProviderException,
|
||||
NoSuchAlgorithmException {
|
||||
|
||||
try {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
|
||||
KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(
|
||||
keyAlias,
|
||||
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
|
||||
.setRandomizedEncryptionRequired(false)
|
||||
.build();
|
||||
|
||||
keyGenerator.init(keyGenParameterSpec);
|
||||
Log.i("KEY_GENERATEOT", keyGenerator.generateKey().toString());
|
||||
return keyGenerator.generateKey();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static SecretKey retrieveKey(String keyAlias) throws Exception {
|
||||
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
|
||||
keyStore.load(null);
|
||||
|
||||
KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore.getEntry(keyAlias, null);
|
||||
return secretKeyEntry.getSecretKey();
|
||||
}
|
||||
|
||||
public static String encrypt(String algorithm, String input, SecretKey key, IvParameterSpec iv) throws
|
||||
NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException,
|
||||
BadPaddingException, IllegalBlockSizeException {
|
||||
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
|
||||
byte[] cipherText = cipher.doFinal(input.getBytes());
|
||||
return Base64.getEncoder().encodeToString(cipherText);
|
||||
}
|
||||
|
||||
public static String decrypt(String algorithm, String cipherText, SecretKey key, IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException, InvalidKeyException,
|
||||
BadPaddingException, IllegalBlockSizeException{
|
||||
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, iv);
|
||||
byte[] plainText = cipher.doFinal(Base64.getDecoder().decode(cipherText));
|
||||
return new String(plainText);
|
||||
}
|
||||
|
||||
public static IvParameterSpec generateIv(){
|
||||
byte[] iv = new byte[16];
|
||||
new SecureRandom().nextBytes(iv);
|
||||
return new IvParameterSpec(iv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user