aes do zrobienia

This commit is contained in:
mikgaw@st.amu.edu.pl 2023-12-05 14:05:57 +01:00
parent 621158df66
commit 081c9cb909
6 changed files with 285 additions and 18 deletions

View File

@ -0,0 +1,51 @@
package com.example.bsm_notatnik;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class AESUtils {
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding"; // Use ECB mode without an IV
public static String encrypt(String data, String key) {
try {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encryptedData = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encryptedData);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
return null;
}
}
public static String decrypt(String encryptedData, String key) {
try {
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] decryptedData = cipher.doFinal(encryptedBytes);
return new String(decryptedData);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,100 @@
package com.example.bsm_notatnik;
import android.os.Build;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import androidx.annotation.RequiresApi;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class CryptoManager {
private final KeyStore keyStore;
public CryptoManager() throws Exception {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
}
private Cipher getEncryptCipher() throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, getKey());
return cipher;
}
private Cipher getDecryptCipherForIv(byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, getKey(), new IvParameterSpec(iv));
return cipher;
}
private SecretKey getKey() throws Exception {
KeyStore.SecretKeyEntry existingKey = (KeyStore.SecretKeyEntry) keyStore.getEntry("secret", null);
return (existingKey != null) ? existingKey.getSecretKey() : createKey();
}
private SecretKey createKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(new KeyGenParameterSpec.Builder(
"secret",
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(BLOCK_MODE)
.setEncryptionPaddings(PADDING)
.setUserAuthenticationRequired(false)
.setRandomizedEncryptionRequired(true)
.build()
);
return keyGenerator.generateKey();
}
public byte[] encrypt(byte[] bytes, OutputStream outputStream) throws Exception {
Cipher encryptCipher = getEncryptCipher();
byte[] encryptedBytes = encryptCipher.doFinal(bytes);
try {
outputStream.write(encryptCipher.getIV().length);
outputStream.write(encryptCipher.getIV());
outputStream.write(encryptedBytes.length);
outputStream.write(encryptedBytes);
} finally {
outputStream.close();
}
return encryptedBytes;
}
public byte[] decrypt(InputStream inputStream) throws Exception {
byte[] iv;
byte[] encryptedBytes;
try {
int ivSize = inputStream.read();
iv = new byte[ivSize];
inputStream.read(iv);
int encryptedBytesSize = inputStream.read();
encryptedBytes = new byte[encryptedBytesSize];
inputStream.read(encryptedBytes);
} finally {
inputStream.close();
}
return getDecryptCipherForIv(iv).doFinal(encryptedBytes);
}
private static final String ALGORITHM = KeyProperties.KEY_ALGORITHM_AES;
private static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC;
private static final String PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7;
private static final String TRANSFORMATION = ALGORITHM + "/" + BLOCK_MODE + "/" + PADDING;
}

View File

@ -96,9 +96,9 @@ public class Login extends AppCompatActivity {
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;
@ -107,6 +107,7 @@ public class Login extends AppCompatActivity {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("CURRENT_USER_EMAIL_HASH", hashedemail);
intent.putExtra("KEY_HASH", genKeyHash(hashedemail, password));
startActivity(intent);
finish();
@ -116,10 +117,23 @@ public class Login extends AppCompatActivity {
}
}
private byte[] getSaltForUser(String hashedemail){
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);
String saltFromData = sharedPreferences.getString("salt_" + hashedemail, "err");
String saltFromData;
if (salt2){
saltFromData = sharedPreferences.getString("salt_2_" + hashedEmail, "err");
}
else {
saltFromData = sharedPreferences.getString("salt_" + hashedEmail, "err");
}
return Base64.getDecoder().decode(saltFromData);
}
}

View File

@ -3,6 +3,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
@ -14,32 +15,53 @@ import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class MainActivity extends AppCompatActivity {
private CryptoManager cryptoManager;
Button buttonLogout, buttonChangePassword, buttonAddNewNote;
private static final String SHARED_NAME_CREDENTIALS = "Credentials";
private static final String SHARED_NOTES_NAME = "Notes";
private static String HASHED_EMAIL = "";
private static String KEY_HASH = "";
private List<Note> noteList;
private LinearLayout notesContainer;
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
cryptoManager = new CryptoManager();
} catch (Exception e) {
e.printStackTrace(); // Handle exceptions according to your needs
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
String current_username_hashed = intent.getStringExtra("CURRENT_USER_EMAIL_HASH");
HASHED_EMAIL = current_username_hashed;
KEY_HASH = intent.getStringExtra("KEY_HASH");
notesContainer = findViewById(R.id.notesContainer);
noteList = new ArrayList<>();
@ -50,6 +72,8 @@ public class MainActivity extends AppCompatActivity {
buttonChangePassword = findViewById(R.id.btn_change_password);
buttonAddNewNote = findViewById(R.id.btn_add_note);
Log.i("KURWAAAAAAAAAAAAAAAAA", KEY_HASH);
buttonLogout.setOnClickListener(view -> logOut());
buttonChangePassword.setOnClickListener(view -> showPasswordChangeDialog(current_username_hashed));
@ -134,24 +158,32 @@ public class MainActivity extends AppCompatActivity {
String newSaltString = Base64.getEncoder().encodeToString(newSalt);
editor.putString("salt_" + hashedEmail, newSaltString);
String hashedNewPassword = Utility.hashCredential(newPassword, newSalt);
String hashedNewPassword = Utility.hashCredential(newPassword, newSalt, 1000);
editor.putString("user_" + hashedEmail, hashedNewPassword);
editor.apply();
}
private boolean validateOldPassword(String hashedEmail, String oldPassword){
byte[] salt = getSaltForUser(hashedEmail);
String hashedOldPassword = Utility.hashCredential(oldPassword, salt);
byte[] salt = getSaltForUser(hashedEmail, false);
String hashedOldPassword = Utility.hashCredential(oldPassword, salt, 1000);
String hashedCorrectPassword = getPasswordFromShared(hashedEmail);
assert hashedOldPassword != null;
return hashedOldPassword.equals(hashedCorrectPassword);
}
private byte[] getSaltForUser(String hashedEmail){
private byte[] getSaltForUser(String hashedEmail, boolean salt2){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NAME_CREDENTIALS, MODE_PRIVATE);
String saltFromData = sharedPreferences.getString("salt_" + hashedEmail, "err");
String saltFromData;
if (salt2){
saltFromData = sharedPreferences.getString("salt_2_" + hashedEmail, "err");
}
else {
saltFromData = sharedPreferences.getString("salt_" + hashedEmail, "err");
}
return Base64.getDecoder().decode(saltFromData);
}
private String getPasswordFromShared(String hashedEmail){
@ -241,9 +273,6 @@ public class MainActivity extends AppCompatActivity {
alertDialog.show();
}
private void genSecretKey(){
}
private void saveNotesToPreferences(String mode){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_NOTES_NAME, MODE_PRIVATE);
@ -259,9 +288,11 @@ public class MainActivity extends AppCompatActivity {
editor.putInt("notecount_" + HASHED_EMAIL, noteList.size());
for(int i=0; i<noteList.size(); i++){
Note note = noteList.get(i);
editor.putString(i + "_title_" + HASHED_EMAIL, note.getTitle());
editor.putString(i + "_title_" + HASHED_EMAIL, encryptCesar(note.getTitle(), 2));
editor.putString(i + "_content_" + HASHED_EMAIL, note.getContent());
}
editor.apply();
}
@ -275,7 +306,7 @@ public class MainActivity extends AppCompatActivity {
String content = sharedPreferences.getString(i + "_content_" + HASHED_EMAIL, "");
Note note = new Note();
note.setTitle(title);
note.setTitle(decryptCesar(title, 2));
note.setContent(content);
noteList.add(note);
@ -333,20 +364,91 @@ public class MainActivity extends AppCompatActivity {
}
}
private static final byte[] CONSTANT_IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
// Function to encrypt a message using AES in CBC mode with a constant IV
public static String encrypt(String data, String key) {
try {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
// Use the constant IV
IvParameterSpec ivParameterSpec = new IvParameterSpec(CONSTANT_IV);
// Create a SecretKeySpec using the provided key
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
// Initialize the cipher for encryption
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
// Encrypt the data
byte[] encryptedBytes = cipher.doFinal(data.getBytes());
// Combine IV and encrypted data for later decryption
byte[] combined = new byte[CONSTANT_IV.length + encryptedBytes.length];
System.arraycopy(CONSTANT_IV, 0, combined, 0, CONSTANT_IV.length);
System.arraycopy(encryptedBytes, 0, combined, CONSTANT_IV.length, encryptedBytes.length);
// Base64 encode the result for easy storage and transmission
return Base64.getEncoder().encodeToString(combined);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// Function to decrypt a message using AES in CBC mode with a constant IV
public static String decrypt(String encryptedData, String key) {
try {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
// Decode the Base64-encoded input
byte[] combined = Base64.getDecoder().decode(encryptedData);
// Extract IV from the combined data
byte[] iv = new byte[CONSTANT_IV.length];
System.arraycopy(combined, 0, iv, 0, CONSTANT_IV.length);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Create a SecretKeySpec using the provided key
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
// Initialize the cipher for decryption
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
// Decrypt the data
byte[] decryptedBytes = cipher.doFinal(combined, CONSTANT_IV.length, combined.length - CONSTANT_IV.length);
return new String(decryptedBytes);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// Function to encrypt a message using Caesar Cipher
public static String encryptCesar(String message, int key) {
StringBuilder encryptedMessage = new StringBuilder();
for (char character : message.toCharArray()) {
if (Character.isLetter(character)) {
char base = Character.isUpperCase(character) ? 'A' : 'a';
char encryptedChar = (char) ((character - base + key) % 26 + base);
encryptedMessage.append(encryptedChar);
} else {
// Keep non-alphabetic characters unchanged
encryptedMessage.append(character);
}
}
return encryptedMessage.toString();
}
// Function to decrypt a message using Caesar Cipher with a key
public static String decryptCesar(String encryptedMessage, int key) {
return encryptCesar(encryptedMessage, 26 - (key % 26)); // Decryption is equivalent to shifting in the opposite direction
}

View File

@ -102,7 +102,7 @@ public class Register extends AppCompatActivity {
saveSaltsForUser(hashedEmail, salt1, salt2);
hashedPassword = Utility.hashCredential(password, salt1);
hashedPassword = Utility.hashCredential(password, salt1, 1000);
saveNewUser(hashedEmail, hashedPassword);

View File

@ -25,10 +25,10 @@ public class Utility {
byte[] emailSalt;
emailSalt = getFirst16BytesOfHash(email);
return hashCredential(email, emailSalt);
return hashCredential(email, emailSalt, 1000);
}
protected static String hashCredential(String credential, byte[] salt){
int iteratiions = 1000;
protected static String hashCredential(String credential, byte[] salt, int iterations){
int iteratiions = iterations;
int keyLen = 256;
KeySpec keySpec = new PBEKeySpec(credential.toCharArray(), salt, iteratiions, keyLen);