Commit ca568652 by Pedro Cavaleiro

Recoded menus using enums, fixed AES-CBC Encryption/Decryption now with blocks,…

Recoded menus using enums, fixed AES-CBC Encryption/Decryption now with blocks, added file validation (through digital signature), added help menu, moved portions of code onto new funcions for cleaner code, file restore is now implemented and fully working restoring files onto a folder Restored
parent 0a69f66c
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
#Thu Nov 30 15:36:00 WET 2017
cyphertype=aes_cbc
cfgexists=1
>>>>>>>=master
keysize=16
<<<<<<<=HEAD
encrypted=Fall_Into_Oblivion\\Trashed\\ola.txt,Fall_Into_Oblivion\\Trashed\\ola - Copy (3).txt,Fall_Into_Oblivion\\Trashed\\ola - Copy (4).txt,Fall_Into_Oblivion\\Trashed\\ola - Copy.txt,Fall_Into_Oblivion/Trashed/asd 2.txt,Fall_Into_Oblivion/Trashed/asd 3.txt,Fall_Into_Oblivion/Trashed/pasta sem nome.zip,Fall_Into_Oblivion/Trashed/asd 7.txt,Fall_Into_Oblivion/Trashed/asd 6.txt,Fall_Into_Oblivion/Trashed/asd 4.txt,Fall_Into_Oblivion/Trashed/asd 5.txt,Fall_Into_Oblivion/Trashed/pasta sem nome 5.zip,Fall_Into_Oblivion/Trashed/pasta sem nome 2.zip,Fall_Into_Oblivion/Trashed/asd.txt,Fall_Into_Oblivion/Trashed/pasta sem nome 3.zip,Fall_Into_Oblivion/Trashed/pasta sem nome 4.zip
setenabled=true
filevalidation=digital_signature
=\=\=\=\=\=\=
hashtype=sha256
package fallintooblivion; package fallintooblivion;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.io.*;
public class AES_CBC { public class AES_CBC {
/** /**
* Encripta um ficheiro usando AES-CBC * Encripta um ficheiro por blocos de 1024 bytes
* @param key chave the encriptação * @param in stream de entrada
* @param IV IV * @param out stream de saida
* @param file bytes do ficheiro a encriptar * @param password password/chave
* @return bytes do ficheiro encriptado * @param iv iv
* @throws Exception Excepção generica
*/ */
public static byte[] encrypt(String key, String IV, byte[] file) { public static void encrypt(InputStream in, OutputStream out, String password, String iv) throws Exception{
try {
IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); Cipher cipher = Cipher.getInstance("AES/CFB8/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(file); out = new CipherOutputStream(out, cipher);
byte[] buf = new byte[1024];
return encrypted; int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
} catch (Exception ex) { out.write(buf, 0, numRead);
ex.printStackTrace();
} }
out.close();
return null;
} }
/** /**
* Desencripta um ficheiro que foi encriptado usando AES-CBC * Desencripta um ficheiro por blocos de 1024 bytes
* @param key chave para desencriptar * @param in stream de entrada
* @param IV IV usado para encriptar * @param out stream de saida
* @param file bytes do ficheiro a desencriptar * @param password password/chave
* @return bytes do ficheiro a encriptar * @param iv iv
* @throws Exception Excepção genérica
*/ */
public static byte[] decrypt(String key, String IV, byte[] file) { public static void decrypt(InputStream in, OutputStream out, String password, String iv) throws Exception{
try {
IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); Cipher cipher = Cipher.getInstance("AES/CFB8/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] original = file; in = new CipherInputStream(in, cipher);
byte[] buf = new byte[1024];
return original; int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
} catch (Exception ex) { out.write(buf, 0, numRead);
ex.printStackTrace();
} }
out.close();
}
return null; /**
* Define se vai efetuar encriptação ou desencriptação copiando o ficheiro
* @param mode modo da cifra (ENCRYPT_MODE / DECRYPT_MODE)
* @param inputFile Ficheiro de entrada
* @param outputFile Ficheiro de saida
* @param password password/chave
* @param iv iv
* @throws Exception Excepção genérica
*/
public static void copy(int mode, String inputFile, String outputFile, String password, String iv) throws Exception {
BufferedInputStream is = new BufferedInputStream(new FileInputStream(inputFile));
BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile));
if(mode==Cipher.ENCRYPT_MODE){
encrypt(is, os, password, iv);
}
else if(mode==Cipher.DECRYPT_MODE){
decrypt(is, os, password, iv);
}
else throw new Exception("unknown mode");
is.close();
os.close();
} }
} }
\ No newline at end of file
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
*/ */
package fallintooblivion; package fallintooblivion;
import javax.crypto.Cipher;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
...@@ -46,7 +47,7 @@ public class Helpers { ...@@ -46,7 +47,7 @@ public class Helpers {
* @return devolve os bytes do ficheiro * @return devolve os bytes do ficheiro
* @throws Exception * @throws Exception
*/ */
public static byte[] lerFicheiro(String filePath) throws Exception{ public static byte[] readFile(String filePath) throws Exception {
File file = new File(filePath); File file = new File(filePath);
byte[] getBytes = new byte[(int) file.length()]; byte[] getBytes = new byte[(int) file.length()];
FileInputStream fsIn = new FileInputStream(file); FileInputStream fsIn = new FileInputStream(file);
...@@ -62,12 +63,225 @@ public class Helpers { ...@@ -62,12 +63,225 @@ public class Helpers {
* @param bytes Bytes para serem escritos * @param bytes Bytes para serem escritos
* @throws Exception Excepção generica * @throws Exception Excepção generica
*/ */
public static void escreverFicheiro(String filepath, String extension, byte[] bytes) throws Exception { public static void writeFile(String filepath, String extension, byte[] bytes) throws Exception {
FileOutputStream fsOut = new FileOutputStream(filepath + "." + extension); FileOutputStream fsOut = new FileOutputStream(filepath + extension);
fsOut.write(bytes); fsOut.write(bytes);
fsOut.close(); fsOut.close();
} }
} }
public static class CommandsHelper {
public static class Exception extends java.lang.Exception {
public CommandsHelper.Exception.Exceptions getFlag() {
return flag;
}
private CommandsHelper.Exception.Exceptions flag;
public enum Exceptions {
unknownCommand,
unknownOption
}
public Exception (String message, CommandsHelper.Exception.Exceptions flag) {
super (message);
this.flag = flag;
}
}
public static final String availableCommands =
"Available commands:\n" +
"restorefile validatefile setcypher sethash setenabled showconfig help exit\n";
public static final String restoreFileOptionsString =
"restorefile [options]\n" +
"-l Lists all the files in the trash\n" +
"-p <File> The pin to decrypt the file\n";
public static final String validateFileCommandString = "validate [file]\n" +
"INFO: If the file is in the restored directory you will only need to type the filename\n" +
"NOTE: The public key and the signature file must be in the same directory\n";
public static final String setCypherCommandString =
"setcypher [cyphertype] [keysize]\n" +
"Cypher Types:\naes_cbc\n";
// Não irá ser mostrada, apenas a verificação via Assinatura digital se encontra
// totalmente implementada e funcional
public static final String setFileValidationCommandString =
"setvalidation [validationmethod]\n" +
"Available Methods:\nhash\ndigital_signature\n";
public static final String setHashCommandString =
"sethash [hashtype]\n" +
"Hash Algorithms:\nsha256\n";
public static final String helpString =
"\nFile Restore\n" + restoreFileOptionsString +
"\n\nFile Validation\n" + validateFileCommandString +
"\n\nSettings Manager\n" + setCypherCommandString + "\n" + setHashCommandString + "\n" +
"setenabled [boolean]\n";
/**
* All the commands supported by the program
*/
public enum Commands {
help,
restorefile,
validatefile,
setcypher,
setvalidation,
sethash,
setenabled,
showconfig,
exit
}
/**
* All the options available for the restorefile command
*/
public enum RestoreFileOptions {
listfiles,
decryptfile
}
/**
* Traduz uma string para o comando correto
* @param command string que contem o comando
* @return enum do comando para facilitar a utilização
* @throws CommandsHelper.Exception excepção de comando não encontrado
*/
public static Commands translateToCommand(String command) throws CommandsHelper.Exception {
switch (command) {
case "restorefile":
return Commands.restorefile;
case "validatefile":
return Commands.validatefile;
case "setcypher":
return Commands.setcypher;
case "setvalidation":
return Commands.setvalidation;
case "sethash":
return Commands.sethash;
case "setenabled":
return Commands.setenabled;
case "showconfig":
return Commands.showconfig;
case "exit":
return Commands.exit;
case "help":
return Commands.help;
default:
throw new CommandsHelper.Exception("Unknown Command", Exception.Exceptions.unknownCommand);
}
}
/**
* Traduz uma string para a opção correta
* @param string opção introduzida
* @return enum da opção para facilitar a utilização
* @throws CommandsHelper.Exception excepção de opção não encontrada
*/
public static RestoreFileOptions translateToRestoreFileOption(String string) throws CommandsHelper.Exception {
switch (string) {
case "-l":
return RestoreFileOptions.listfiles;
case "-p":
return RestoreFileOptions.decryptfile;
default:
throw new CommandsHelper.Exception("Unknown option" + string + "for command restorefile",
Exception.Exceptions.unknownOption);
}
}
}
public static class Encryptor {
/**
* Encrypta um ficheiro dado um nome do ficheiro e caminho e o cypher a ser usado
* @param fileName nome do ficheiro
* @param filePath caminho para o ficheiro
* @param cypher cypher a ser usado
*/
public static void Encrypt(String fileName, String filePath, String cypher) {
try {
String outFile = "Fall_Into_Oblivion/Trashed/" + fileName + "/" + fileName;
// TEMPORARY debugging purposes only
// Create the hash of the pin 0000
// So far we were only able to use 16 Byte key
// 24 Byte or 32 Byte will say Invalid Key Size, even though it's a valid key size
// TODO: Randomize 3 or 4 digit pin without printing it to the user
String pinHASH = SHA256.calculateStringMAC("0000");
pinHASH = pinHASH.subSequence(0, 16).toString();
// Encrypt the file using the defined cypher type, it defaults to AES-CBC
switch (cypher) {
case "aes_cbc":
outFile += ".aescbc";
AES_CBC.copy(Cipher.ENCRYPT_MODE, filePath, outFile , pinHASH,"0000000000000000");
break;
default:
outFile += ".aescbc";
AES_CBC.copy(Cipher.ENCRYPT_MODE, filePath, outFile , pinHASH,"0000000000000000");
break;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
/**
* Decripta um ficheiro dado um pin e o caminho para o ficheiro
* @param pin Pin para desencriptar
* @param file ficheiro para desencriptar
*/
public static void Decrypt(String pin, String file) {
try {
// Calcular o HASH usando SHA256 do pin e gerar a chave de 16 bytes
String pinHASH = SHA256.calculateStringMAC(pin);
pinHASH = pinHASH.subSequence(0, 16).toString();
// Carregar o ficheiro encriptado para memoria, desencriptar e guardar
// TODO: not all files will be aescbc
File encFile = new File("Fall_Into_Oblivion/Trashed/" + file + "/" + file + ".aescbc");
// Criar a pasta que vai guardar a assinatura e o novo ficheiro
File folder = new File("Fall_Into_Oblivion/Restored/" + file);
if (!folder.exists()) {
folder.mkdir();
}
String outFile = "Fall_Into_Oblivion/Restored/" + file + "/" + file;
AES_CBC.copy(Cipher.DECRYPT_MODE, encFile.getAbsolutePath(), outFile,
pinHASH, "0000000000000000");
Helpers.FileHelpers.writeFile(outFile, ".sig",
Helpers.FileHelpers.readFile("Fall_Into_Oblivion/Trashed/" + file + "/" + file + ".sig"));
Helpers.FileHelpers.writeFile(outFile, ".pk",
Helpers.FileHelpers.readFile("Fall_Into_Oblivion/Trashed/" + file + "/" + file + ".pk"));
File dir = new File("Fall_Into_Oblivion/Trashed/" + file + "/");
Helpers.FileHelpers.deleteDirectory(dir);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
} }
package fallintooblivion; package fallintooblivion;
import java.io.*; import java.io.*;
public class Ler{ public class Reader {
/** public static class Exception extends java.lang.Exception {
* Lê uma string do buffer
* @return string lida public Exceptions getFlag() {
*/ return flag;
public static String umaString (){ }
String s = "";
try{ private Exceptions flag;
BufferedReader in = new BufferedReader ( new InputStreamReader (System.in));
s= in.readLine(); public enum Exceptions {
} stringReaderError,
catch (IOException e){ intReaderError,
System.out.println("Opção não válida."); doubleReaderError,
System.out.print(""); booleanReaderError
} }
return s;
} public Exception (String message, Exceptions flag) {
super (message);
/** this.flag = flag;
* Lê um int do buffer }
* @return int lido
*/ }
public static int umInt(){
while(true){ /**
try{ * Lê uma string do buffer
return Integer.valueOf(umaString().trim()).intValue(); * @return string lida
} */
catch(Exception e){ public static String readString () throws Reader.Exception {
System.out.println("Opção não válida."); String s = "";
System.out.print(""); try{
} BufferedReader in = new BufferedReader ( new InputStreamReader (System.in));
} s= in.readLine();
} }
catch (IOException e){
/** throw new Reader.Exception("Unable to read the string", Exception.Exceptions.stringReaderError);
* Lê um double do buffer }
* @return double lido return s;
*/ }
public static double umDouble(){
while(true){ /**
try{ * Lê um int do buffer
return Double.valueOf(umaString().trim()).doubleValue(); * @return int lido
} */
catch(Exception e){ public static int readInt() throws Reader.Exception {
System.out.println("Opção não válida."); while(true){
System.out.print(""); try{
} return Integer.valueOf(readString().trim()).intValue();
} }
} catch(Exception e){
} throw new Reader.Exception("Unable to read the integer", Exception.Exceptions.intReaderError);
}
}
}
/**
* Lê um double do buffer
* @return double lido
*/
public static double readDouble() throws Reader.Exception {
while(true){
try{
return Double.valueOf(readString().trim()).doubleValue();
}
catch(Exception e){
throw new Reader.Exception("Unable to read the double", Exception.Exceptions.doubleReaderError);
}
}
}
/**
* Lê um boolean do buffer
* @return
*/
public static boolean readBool() throws Reader.Exception {
while(true) {
try {
return Boolean.parseBoolean(readString().trim().toLowerCase());
} catch (Exception ex) {
throw new Reader.Exception("Unable to read the boolean", Exception.Exceptions.booleanReaderError);
}
}
}
}
/* /*
* To change this license header, choose License Headers in Project Properties. * To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package fallintooblivion; package fallintooblivion;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import static java.lang.System.in; import static java.lang.System.in;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SignatureException; import java.security.SignatureException;
/** /**
* *
* @author ricar * @author ricar
*/ */
public class mainASSINATURA { public class functionsDebug {
public static void main(String[] args) throws NoSuchAlgorithmException, IOException, FileNotFoundException, SignatureException, InvalidKeyException, Exception { public static void main(String[] args) {
Assinatura a= new Assinatura(); }
//a.gerarChaves("ola.txt", "signature", "pubKey");
//System.out.println(a.verificaAssinatura("Fall_Into_Oblivion/Trashed/Sem nome.rtf/Sem", "signature", "pubKey")); }
//SHA256.calculateStringMAC("teste");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment