Files
Bankapp/src/main/java/me/zacharias/bank/Utils.java

153 lines
4.9 KiB
Java

package me.zacharias.bank;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class Utils {
public static final Gson gson;
static {
GsonBuilder gsonBuilder = new GsonBuilder();
//gsonBuilder.registerTypeAdapter(Account.class, new AccountAdapter());
gson = gsonBuilder.create();
File users = new File("./users");
if(!users.exists()) {
users.mkdir();
}
}
public static String SHA256(String input) {
MessageDigest sha256 = null;
try {
sha256 = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] hash = sha256.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
private static final int KEY_SIZE = 256;
private static final int ITERATIONS = 65536;
private static final int SALT_LENGTH = 16;
private static final int IV_LENGTH = 12;
public static String Encrypt(String data, String username) throws Exception {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[SALT_LENGTH];
random.nextBytes(salt);
byte[] iv = new byte[IV_LENGTH];
random.nextBytes(iv);
SecretKey key = deriveKey(username, salt);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, gcmSpec);
byte[] encryptedData = cipher.doFinal(data.getBytes());
byte[] combined = new byte[salt.length + iv.length + encryptedData.length];
System.arraycopy(salt, 0, combined, 0, salt.length);
System.arraycopy(iv, 0, combined, salt.length, iv.length);
System.arraycopy(encryptedData, 0, combined, salt.length + iv.length, encryptedData.length);
return Base64.getEncoder().encodeToString(combined);
}
public static String Decrypt(String data, String username) throws Exception {
byte[] combined = Base64.getDecoder().decode(data);
// Extract salt, IV, and encrypted data
byte[] salt = new byte[SALT_LENGTH];
byte[] iv = new byte[IV_LENGTH];
byte[] cipherText = new byte[combined.length - SALT_LENGTH - IV_LENGTH];
System.arraycopy(combined, 0, salt, 0, salt.length);
System.arraycopy(combined, salt.length, iv, 0, iv.length);
System.arraycopy(combined, salt.length + iv.length, cipherText, 0, cipherText.length);
SecretKey key = deriveKey(username, salt);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, key, gcmSpec);
byte[] decrptedData = cipher.doFinal(cipherText);
return new String(decrptedData);
}
private static SecretKey deriveKey(String password, byte[] salt) throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_SIZE);
return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
}
public static String ReadFile(File file)
{
if(!file.exists())
{
throw new RuntimeException(new FileNotFoundException(file.getPath()+" not found"));
}
try {
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
String line;
while((line = br.readLine()) != null)
{
sb.append(line);
}
return sb.toString();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
public static void WriteFile(File file, String data) {
if(file.exists())
{
file.delete();
}
try {
file.createNewFile();
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write(data);
bw.close();
}catch (IOException e)
{
throw new RuntimeException(e);
}
}
}