This commit is contained in:
mikgaw@st.amu.edu.pl 2023-12-05 23:53:17 +01:00
parent 3b1d7039d0
commit ad9b2aa6a9
8 changed files with 127 additions and 190 deletions

View File

@ -6,33 +6,26 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64; import java.util.Base64;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class Login extends AppCompatActivity { public class Login extends AppCompatActivity {
private static final String SHARED_NAME_CREDENTIALS = "Credentials"; private static final String SHARED_NAME_CREDENTIALS = "Credentials";
EditText editTextEmail, editTextPassword; EditText editTextEmail, editTextPassword;
Button buttonLogin; Button buttonLogin;
ProgressBar progressBar;
TextView textView; TextView textView;
private static final int MAX_LOGIN_ATTEMPTS = 5;
private static final long LOGIN_LOCKOUT_TIME = 60000;
private int loginAttempts = 0;
private long lastLoginAttemptTime = 0;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -42,30 +35,37 @@ public class Login extends AppCompatActivity {
editTextEmail = findViewById(R.id.username); editTextEmail = findViewById(R.id.username);
editTextPassword = findViewById(R.id.password); editTextPassword = findViewById(R.id.password);
buttonLogin = findViewById(R.id.btn_login); buttonLogin = findViewById(R.id.btn_login);
progressBar = findViewById(R.id.progressBar);
textView = findViewById(R.id.registerNow); textView = findViewById(R.id.registerNow);
textView.setOnClickListener(new View.OnClickListener() { textView.setOnClickListener(view -> {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), Register.class); Intent intent = new Intent(getApplicationContext(), Register.class);
startActivity(intent); startActivity(intent);
finish(); // finishes current activity finish(); // finishes current activity
}
}); });
buttonLogin.setOnClickListener(new View.OnClickListener() { buttonLogin.setOnClickListener(view -> {
@Override long currentTime = System.currentTimeMillis();
public void onClick(View view) { if (currentTime - lastLoginAttemptTime >= LOGIN_LOCKOUT_TIME) {
//progressBar.setVisibility(View.VISIBLE); loginAttempts = 0;
String email, hashedEmail, password; }
email = String.valueOf(editTextEmail.getText()); loginAttempts++;
lastLoginAttemptTime = currentTime;
if (loginAttempts > MAX_LOGIN_ATTEMPTS) {
Toast.makeText(Login.this, "Too many login attempts.", Toast.LENGTH_SHORT).show();
return;
}
String email, hashedEmail, password;
email = String.valueOf(editTextEmail.getText());
hashedEmail = Utility.hashEmail(email); hashedEmail = Utility.hashEmail(email);
password = String.valueOf(editTextPassword.getText()); password = String.valueOf(editTextPassword.getText());
if (TextUtils.isEmpty(email)){ if (TextUtils.isEmpty(email)){
Toast.makeText(Login.this, "Enter email!", Toast.LENGTH_SHORT).show(); Toast.makeText(Login.this, "Enter email!", Toast.LENGTH_SHORT).show();
return; return;
@ -80,32 +80,23 @@ public class Login extends AppCompatActivity {
return; return;
} }
try {
login(hashedEmail, password); login(hashedEmail, password);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (InvalidKeySpecException e) {
throw new RuntimeException(e);
}
//progressBar.setVisibility(View.GONE);
}
}); });
} }
private boolean checkIfUserExists(String hashedemail){ private boolean checkIfUserExists(String hashedEmail){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE); SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE);
return sharedPreferences.contains("user_" + hashedemail); return sharedPreferences.contains("user_" + hashedEmail);
} }
private void login(String hashedemail, String password) throws NoSuchAlgorithmException, InvalidKeySpecException { private void login(String hashedEmail, String password) {
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE); SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE);
String passwordHashFromData = sharedPreferences.getString("user_" + hashedemail, "err"); String passwordHashFromData = sharedPreferences.getString("user_" + hashedEmail, "err");
byte[] salt = getSaltForUser(hashedEmail);
byte[] salt = getSaltForUser(hashedemail, false); String inputPasswordHash = Utility.hashCredential(password, salt);
String inputPasswordHash = Utility.hashCredential(password, salt, 1000);
assert inputPasswordHash != null; assert inputPasswordHash != null;
@ -113,8 +104,7 @@ public class Login extends AppCompatActivity {
Toast.makeText(getApplicationContext(), "Login Successful", Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), "Login Successful", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class); Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("CURRENT_USER_EMAIL_HASH", hashedemail); intent.putExtra("CURRENT_USER_EMAIL_HASH", hashedEmail);
//intent.putExtra("KEY", getKeyFromPassword(password, getSalt2(hashedemail)));
intent.putExtra("PAS", password); intent.putExtra("PAS", password);
startActivity(intent); startActivity(intent);
finish(); finish();
@ -125,37 +115,10 @@ public class Login extends AppCompatActivity {
} }
} }
public static SecretKey getKeyFromPassword(String password, String salt) throws NoSuchAlgorithmException, InvalidKeySpecException { private byte[] getSaltForUser(String hashedEmail){
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 65536, 256);
SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
return secret;
}
private String genKeyHash(String hashedemail, String password){
byte[] salt2 = getSaltForUser(hashedemail, true);
return Utility.hashCredential(password, salt2, 5000);
}
private byte[] getSaltForUser(String hashedEmail, boolean salt2){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE); SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE);
String saltFromData; String saltFromData = sharedPreferences.getString("salt_" + hashedEmail, "err");
if (salt2){
saltFromData = sharedPreferences.getString("salt_2_" + hashedEmail, "err");
}
else {
saltFromData = sharedPreferences.getString("salt_" + hashedEmail, "err");
}
return Base64.getDecoder().decode(saltFromData); return Base64.getDecoder().decode(saltFromData);
}
private String getSalt2(String hashedEmail){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE);
return sharedPreferences.getString("salt_2_" + hashedEmail, "err");
} }
} }

View File

@ -1,4 +1,5 @@
package com.example.bsm_notatnik; package com.example.bsm_notatnik;
import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
@ -106,7 +107,7 @@ public class MainActivity extends AppCompatActivity {
} }
if(!validatePassword(newPassword)){ if(!validatePassword(newPassword)){
Toast.makeText(MainActivity.this, "Wrong format of new password!", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "New password to weak!", Toast.LENGTH_SHORT).show();
return; return;
} }
@ -160,9 +161,10 @@ public class MainActivity extends AppCompatActivity {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
createNoteView(note); createNoteView(note);
}
Toast.makeText(MainActivity.this, "Note saved!", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Note saved!", Toast.LENGTH_SHORT).show();
}
}); });
builder.setNegativeButton("Cancel", (dialogInterface, i) -> dialogInterface.dismiss()); builder.setNegativeButton("Cancel", (dialogInterface, i) -> dialogInterface.dismiss());
@ -239,7 +241,7 @@ public class MainActivity extends AppCompatActivity {
private boolean validatePassword(String password){ private boolean validatePassword(String password){
final String PASSWORD_PATTERN = "^.{6,}$"; final String PASSWORD_PATTERN = "^(?=.*[0-9])(?=.*[A-Z])(.{8,})$";
Pattern pattern = Pattern.compile(PASSWORD_PATTERN); Pattern pattern = Pattern.compile(PASSWORD_PATTERN);
Matcher matcher = pattern.matcher(password); Matcher matcher = pattern.matcher(password);
@ -254,7 +256,7 @@ public class MainActivity extends AppCompatActivity {
String newSaltString = Base64.getEncoder().encodeToString(newSalt); String newSaltString = Base64.getEncoder().encodeToString(newSalt);
editor.putString("salt_" + hashedEmail, newSaltString); editor.putString("salt_" + hashedEmail, newSaltString);
String hashedNewPassword = Utility.hashCredential(newPassword, newSalt, 1000); String hashedNewPassword = Utility.hashCredential(newPassword, newSalt);
editor.putString("user_" + hashedEmail, hashedNewPassword); editor.putString("user_" + hashedEmail, hashedNewPassword);
editor.apply(); editor.apply();
@ -264,7 +266,7 @@ public class MainActivity extends AppCompatActivity {
private boolean validateOldPassword(String hashedEmail, String oldPassword){ private boolean validateOldPassword(String hashedEmail, String oldPassword){
byte[] salt = getSaltForUser(hashedEmail, false); byte[] salt = getSaltForUser(hashedEmail, false);
String hashedOldPassword = Utility.hashCredential(oldPassword, salt, 1000); String hashedOldPassword = Utility.hashCredential(oldPassword, salt);
String hashedCorrectPassword = gerPasswordHashFromShared(hashedEmail); String hashedCorrectPassword = gerPasswordHashFromShared(hashedEmail);
assert hashedOldPassword != null; assert hashedOldPassword != null;
@ -313,7 +315,7 @@ public class MainActivity extends AppCompatActivity {
for(int i=0; i<noteList.size(); i++){ for(int i=0; i<noteList.size(); i++){
Note note = noteList.get(i); Note note = noteList.get(i);
editor.putString(i + "_title_" + HASHED_EMAIL, UtilityAES.encrypt("AES/CBC/PKCS5Padding", note.getTitle(), UtilityAES.getKeyFromPassword(PAS, getSaltForUser(HASHED_EMAIL, true)), iv)); editor.putString(i + "_title_" + HASHED_EMAIL, UtilityAES.encrypt("AES/CBC/PKCS5Padding", note.getTitle(), UtilityAES.getKeyFromPassword(PAS, getSaltForUser(HASHED_EMAIL, true)), iv));
editor.putString(i + "_content_" + HASHED_EMAIL, note.getContent()); editor.putString(i + "_content_" + HASHED_EMAIL, UtilityAES.encrypt("AES/CBC/PKCS5Padding", note.getContent(), UtilityAES.getKeyFromPassword(PAS, getSaltForUser(HASHED_EMAIL, true)), iv));
} }
@ -335,7 +337,7 @@ public class MainActivity extends AppCompatActivity {
Note note = new Note(); Note note = new Note();
note.setTitle(UtilityAES.decrypt("AES/CBC/PKCS5Padding", title, UtilityAES.getKeyFromPassword(PAS, getSaltForUser(HASHED_EMAIL, true)), iv) ); note.setTitle(UtilityAES.decrypt("AES/CBC/PKCS5Padding", title, UtilityAES.getKeyFromPassword(PAS, getSaltForUser(HASHED_EMAIL, true)), iv) );
note.setContent(content); note.setContent(UtilityAES.decrypt("AES/CBC/PKCS5Padding", content, UtilityAES.getKeyFromPassword(PAS, getSaltForUser(HASHED_EMAIL, true)), iv) );
noteList.add(note); noteList.add(note);
} }
@ -353,8 +355,7 @@ public class MainActivity extends AppCompatActivity {
private String getIVStringFromShared(){ private String getIVStringFromShared(){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_NOTES, MODE_PRIVATE); SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_NOTES, MODE_PRIVATE);
String ivString = sharedPreferences.getString("iv_" + HASHED_EMAIL, "err"); return sharedPreferences.getString("iv_" + HASHED_EMAIL, "err");
return ivString;
} }
private static IvParameterSpec stringToIv(String ivString) { private static IvParameterSpec stringToIv(String ivString) {
@ -369,19 +370,16 @@ public class MainActivity extends AppCompatActivity {
private void createNoteView(final Note note){ private void createNoteView(final Note note){
View noteView = getLayoutInflater().inflate(R.layout.note_item, null); @SuppressLint("InflateParams") View noteView = getLayoutInflater().inflate(R.layout.note_item, null);
TextView noteTitleTextView = noteView.findViewById(R.id.noteTitleTextView); TextView noteTitleTextView = noteView.findViewById(R.id.noteTitleTextView);
TextView noteContentTextView = noteView.findViewById(R.id.noteContentTextView); TextView noteContentTextView = noteView.findViewById(R.id.noteContentTextView);
Button deleteNoteDutton = noteView.findViewById(R.id.btnDeleteNote); Button deleteNoteButton = noteView.findViewById(R.id.btnDeleteNote);
noteTitleTextView.setText(note.getTitle()); noteTitleTextView.setText(note.getTitle());
noteContentTextView.setText(note.getContent()); noteContentTextView.setText(note.getContent());
deleteNoteDutton.setOnClickListener(view -> showDeleteDialog(note)); deleteNoteButton.setOnClickListener(view -> showDeleteDialog(note));
noteView.setOnLongClickListener(view -> { noteView.setOnLongClickListener(view -> {
showEditNoteDialog(note); showEditNoteDialog(note);

View File

@ -4,13 +4,11 @@ public class Note {
private String title; private String title;
private String content; private String content;
private int id;
public Note(){ public Note(){
} }
public Note(String title, String content, int id){ public Note(String title, String content){
this.title = title; this.title = title;
this.content = content; this.content = content;
} }

View File

@ -6,10 +6,8 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -22,10 +20,8 @@ import java.util.regex.Pattern;
public class Register extends AppCompatActivity { public class Register extends AppCompatActivity {
private static final String SHARED_NAME_CREDENTIALS = "Credentials"; private static final String SHARED_NAME_CREDENTIALS = "Credentials";
EditText editTextEmail, editTextPassword; EditText editTextEmail, editTextPassword;
Button buttonReg; Button buttonReg;
ProgressBar progressBar;
TextView loginNowTextView; TextView loginNowTextView;
@ -38,26 +34,18 @@ public class Register extends AppCompatActivity {
editTextEmail = findViewById(R.id.username); editTextEmail = findViewById(R.id.username);
editTextPassword = findViewById(R.id.password); editTextPassword = findViewById(R.id.password);
buttonReg = findViewById(R.id.btn_register); buttonReg = findViewById(R.id.btn_register);
progressBar = findViewById(R.id.progressBar);
loginNowTextView = findViewById(R.id.loginNow); loginNowTextView = findViewById(R.id.loginNow);
//goes to login page //goes to login page
loginNowTextView.setOnClickListener(new View.OnClickListener() { loginNowTextView.setOnClickListener(view -> {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), Login.class); Intent intent = new Intent(getApplicationContext(), Login.class);
startActivity(intent); startActivity(intent);
finish(); // finishes current activity finish(); // finishes current activity
}
}); });
//when register button is clicked //when register button is clicked
buttonReg.setOnClickListener(new View.OnClickListener() { buttonReg.setOnClickListener(view -> {
@Override
public void onClick(View view) {
//progressBar.setVisibility(View.VISIBLE);
String email, hashedEmail, password, hashedPassword; String email, hashedEmail, password, hashedPassword;
email = String.valueOf(editTextEmail.getText()); email = String.valueOf(editTextEmail.getText());
@ -89,35 +77,32 @@ public class Register extends AppCompatActivity {
Toast.makeText(Register.this, "Email format not correct!", Toast.LENGTH_SHORT).show(); Toast.makeText(Register.this, "Email format not correct!", Toast.LENGTH_SHORT).show();
return; return;
} }
//checks password wymagania //checks password requirements
if (!validatePassword(password)){ if (!validatePassword(password)){
Toast.makeText(Register.this, "Password to weak!", Toast.LENGTH_SHORT).show(); Toast.makeText(Register.this, "Password to weak!", Toast.LENGTH_SHORT).show();
return; return;
} }
byte[] salt1 = Utility.generateSalt(); byte[] salt1 = Utility.generateSalt();
byte[] salt2 = Utility.generateSalt(); byte[] salt2 = Utility.generateSalt();
saveSaltsForUser(hashedEmail, salt1, salt2); saveSaltsForUser(hashedEmail, salt1, salt2);
hashedPassword = Utility.hashCredential(password, salt1);
hashedPassword = Utility.hashCredential(password, salt1, 1000);
saveNewUser(hashedEmail, hashedPassword); saveNewUser(hashedEmail, hashedPassword);
Toast.makeText(Register.this, "Konto utworzone z email: " + email + " oraz hasłem: " + password, Toast.LENGTH_SHORT).show(); Toast.makeText(Register.this, "Created account with email: " + email, Toast.LENGTH_SHORT).show();
editTextEmail.setText(""); editTextEmail.setText("");
editTextPassword.setText(""); editTextPassword.setText("");
}
}); });
} }
private boolean checkIfUserExists(String hashedemail){ private boolean checkIfUserExists(String hashedEmail){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE); SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE);
return sharedPreferences.contains("user_" + hashedemail); return sharedPreferences.contains("user_" + hashedEmail);
} }
private boolean validateEmail(String email){ private boolean validateEmail(String email){
@ -129,31 +114,30 @@ public class Register extends AppCompatActivity {
} }
private boolean validatePassword(String password){ private boolean validatePassword(String password){
final String PASSWORD_PATTERN = "^.{6,}$"; final String PASSWORD_PATTERN = "^(?=.*[0-9])(?=.*[A-Z])(.{8,})$";
Pattern pattern = Pattern.compile(PASSWORD_PATTERN); Pattern pattern = Pattern.compile(PASSWORD_PATTERN);
Matcher matcher = pattern.matcher(password); Matcher matcher = pattern.matcher(password);
return matcher.matches(); return matcher.matches();
} }
private void saveSaltsForUser(String hashedemail, byte[] salt1, byte[] salt2){ private void saveSaltsForUser(String hashedEmail, byte[] salt1, byte[] salt2){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE); SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit(); SharedPreferences.Editor editor = sharedPreferences.edit();
String salt1String = Base64.getEncoder().encodeToString(salt1); String salt1String = Base64.getEncoder().encodeToString(salt1);
String salt2String = Base64.getEncoder().encodeToString(salt2); String salt2String = Base64.getEncoder().encodeToString(salt2);
editor.putString("salt_" + hashedemail, salt1String); editor.putString("salt_" + hashedEmail, salt1String);
editor.putString("salt_2_" + hashedemail, salt2String); editor.putString("salt_2_" + hashedEmail, salt2String);
editor.apply(); editor.apply();
} }
private void saveNewUser(String hashedemail, String password){ private void saveNewUser(String hashedEmail, String password){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE); SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit(); SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("user_" + hashedemail, password); editor.putString("user_" + hashedEmail, password);
editor.apply(); editor.apply();
} }
} }

View File

@ -25,13 +25,12 @@ public class Utility {
byte[] emailSalt; byte[] emailSalt;
emailSalt = getFirst16BytesOfHash(email); emailSalt = getFirst16BytesOfHash(email);
return hashCredential(email, emailSalt, 1000); return hashCredential(email, emailSalt);
} }
protected static String hashCredential(String credential, byte[] salt, int iterations){ protected static String hashCredential(String credential, byte[] salt){
int iteratiions = iterations;
int keyLen = 256; int keyLen = 256;
KeySpec keySpec = new PBEKeySpec(credential.toCharArray(), salt, iteratiions, keyLen); KeySpec keySpec = new PBEKeySpec(credential.toCharArray(), salt, 1000, keyLen);
try{ try{
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec); SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
@ -46,21 +45,19 @@ public class Utility {
protected static byte[] getFirst16BytesOfHash(String input){ protected static byte[] getFirst16BytesOfHash(String input){
try { try {
// Create MessageDigest instance for SHA-256
MessageDigest digest = MessageDigest.getInstance("SHA-256"); MessageDigest digest = MessageDigest.getInstance("SHA-256");
// Get the hash value by updating the digest with the input bytes
byte[] hashBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8)); byte[] hashBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8));
// Truncate the hash to the first 16 bytes
byte[] truncatedHash = new byte[16]; byte[] truncatedHash = new byte[16];
System.arraycopy(hashBytes, 0, truncatedHash, 0, 16); System.arraycopy(hashBytes, 0, truncatedHash, 0, 16);
return truncatedHash; return truncatedHash;
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
// Handle the exception (e.g., print an error message)
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
} }

View File

@ -6,7 +6,6 @@ import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec; import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64; import java.util.Base64;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;

View File

@ -1,4 +1,3 @@
<!-- password_change_dialog.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -1,4 +1,3 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"