GOTOWE
This commit is contained in:
parent
3b1d7039d0
commit
ad9b2aa6a9
@ -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,70 +35,68 @@ 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
|
Intent intent = new Intent(getApplicationContext(), Register.class);
|
||||||
public void onClick(View view) {
|
startActivity(intent);
|
||||||
Intent intent = new Intent(getApplicationContext(), Register.class);
|
finish(); // finishes current activity
|
||||||
startActivity(intent);
|
|
||||||
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());
|
|
||||||
|
|
||||||
hashedEmail = Utility.hashEmail(email);
|
|
||||||
password = String.valueOf(editTextPassword.getText());
|
|
||||||
|
|
||||||
if (TextUtils.isEmpty(email)){
|
|
||||||
Toast.makeText(Login.this, "Enter email!", Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (TextUtils.isEmpty(password)){
|
|
||||||
Toast.makeText(Login.this, "Enter password!", Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!checkIfUserExists(hashedEmail)){
|
|
||||||
Toast.makeText(Login.this, "No such username in database!", Toast.LENGTH_SHORT).show();
|
|
||||||
editTextPassword.setText("");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
login(hashedEmail, password);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (InvalidKeySpecException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
//progressBar.setVisibility(View.GONE);
|
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
password = String.valueOf(editTextPassword.getText());
|
||||||
|
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(email)){
|
||||||
|
Toast.makeText(Login.this, "Enter email!", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (TextUtils.isEmpty(password)){
|
||||||
|
Toast.makeText(Login.this, "Enter password!", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!checkIfUserExists(hashedEmail)){
|
||||||
|
Toast.makeText(Login.this, "No such username in database!", Toast.LENGTH_SHORT).show();
|
||||||
|
editTextPassword.setText("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
login(hashedEmail, password);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,86 +34,75 @@ 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
|
Intent intent = new Intent(getApplicationContext(), Login.class);
|
||||||
public void onClick(View view) {
|
startActivity(intent);
|
||||||
Intent intent = new Intent(getApplicationContext(), Login.class);
|
finish(); // finishes current activity
|
||||||
startActivity(intent);
|
|
||||||
finish(); // finishes current activity
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//when register button is clicked
|
//when register button is clicked
|
||||||
buttonReg.setOnClickListener(new View.OnClickListener() {
|
buttonReg.setOnClickListener(view -> {
|
||||||
@Override
|
String email, hashedEmail, password, hashedPassword;
|
||||||
public void onClick(View view) {
|
|
||||||
//progressBar.setVisibility(View.VISIBLE);
|
|
||||||
String email, hashedEmail, password, hashedPassword;
|
|
||||||
|
|
||||||
email = String.valueOf(editTextEmail.getText());
|
email = String.valueOf(editTextEmail.getText());
|
||||||
password = String.valueOf(editTextPassword.getText());
|
password = String.valueOf(editTextPassword.getText());
|
||||||
|
|
||||||
//checks if email field is not empty
|
//checks if email field is not empty
|
||||||
if (TextUtils.isEmpty(email)){
|
if (TextUtils.isEmpty(email)){
|
||||||
Toast.makeText(Register.this, "Enter email!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(Register.this, "Enter email!", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//checks if password field is not empty
|
//checks if password field is not empty
|
||||||
if (TextUtils.isEmpty(password)){
|
if (TextUtils.isEmpty(password)){
|
||||||
Toast.makeText(Register.this, "Enter password!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(Register.this, "Enter password!", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedEmail = Utility.hashEmail(email);
|
hashedEmail = Utility.hashEmail(email);
|
||||||
|
|
||||||
//checks if given username is already registered in database
|
//checks if given username is already registered in database
|
||||||
if (checkIfUserExists(hashedEmail)){
|
if (checkIfUserExists(hashedEmail)){
|
||||||
editTextEmail.setText("");
|
|
||||||
editTextPassword.setText("");
|
|
||||||
Toast.makeText(Register.this, "Account with this username already exists!", Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//checks if email has correct format
|
|
||||||
if (!validateEmail(email)){
|
|
||||||
editTextPassword.setText("");
|
|
||||||
Toast.makeText(Register.this, "Email format not correct!", Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//checks password wymagania
|
|
||||||
if (!validatePassword(password)){
|
|
||||||
Toast.makeText(Register.this, "Password to weak!", Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
byte[] salt1 = Utility.generateSalt();
|
|
||||||
byte[] salt2 = Utility.generateSalt();
|
|
||||||
saveSaltsForUser(hashedEmail, salt1, salt2);
|
|
||||||
|
|
||||||
|
|
||||||
hashedPassword = Utility.hashCredential(password, salt1, 1000);
|
|
||||||
|
|
||||||
saveNewUser(hashedEmail, hashedPassword);
|
|
||||||
|
|
||||||
Toast.makeText(Register.this, "Konto utworzone z email: " + email + " oraz hasłem: " + password, Toast.LENGTH_SHORT).show();
|
|
||||||
editTextEmail.setText("");
|
editTextEmail.setText("");
|
||||||
editTextPassword.setText("");
|
editTextPassword.setText("");
|
||||||
|
Toast.makeText(Register.this, "Account with this username already exists!", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
//checks if email has correct format
|
||||||
|
if (!validateEmail(email)){
|
||||||
|
editTextPassword.setText("");
|
||||||
|
Toast.makeText(Register.this, "Email format not correct!", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//checks password requirements
|
||||||
|
if (!validatePassword(password)){
|
||||||
|
Toast.makeText(Register.this, "Password to weak!", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] salt1 = Utility.generateSalt();
|
||||||
|
byte[] salt2 = Utility.generateSalt();
|
||||||
|
|
||||||
|
saveSaltsForUser(hashedEmail, salt1, salt2);
|
||||||
|
|
||||||
|
hashedPassword = Utility.hashCredential(password, salt1);
|
||||||
|
|
||||||
|
saveNewUser(hashedEmail, hashedPassword);
|
||||||
|
|
||||||
|
Toast.makeText(Register.this, "Created account with email: " + email, Toast.LENGTH_SHORT).show();
|
||||||
|
editTextEmail.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();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user