Cloturation système cryptographique AES_GCM

This commit is contained in:
Jérémi N ‘EndMove’ 2022-03-10 18:17:47 +01:00
parent 826ef9e2e4
commit 555fd095f7
Signed by: EndMove
GPG Key ID: 65C4A02E1F5371A4
5 changed files with 280 additions and 84 deletions

View File

@ -5,10 +5,12 @@ import lightcontainer.protocol.ProtocolReader;
import lightcontainer.protocol.rules.writer.SaveFileErrorRule;
import lightcontainer.protocol.rules.writer.SaveFileOkRule;
import lightcontainer.protocol.rules.writer.SendfileRule;
import lightcontainer.utils.AES_GCM;
import lightcontainer.utils.FileReceiver;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
public class SavefileRule extends ProtocolReader {
// Constants
@ -41,12 +43,18 @@ public class SavefileRule extends ProtocolReader {
System.out.printf("Sauvegarde du fichier : %s %d\n", filename, size);
try {
FileReceiver fileReceiver = new FileReceiver("/home/benjamin/ffe"); // "D:\\");
if (!fileReceiver.receiveFile(reader, this.filename, this.size))
FileReceiver fileReceiver = new FileReceiver("D:\\"); //"/home/benjamin/ffe");
String key = AES_GCM.generateSecretKey();
String iv = AES_GCM.generateIV();
System.out.println("Clé " + key);
System.out.println("IV " + iv);
if (!fileReceiver.receiveFile(reader, this.filename, this.size, key, iv))
throw new IOException();
this.setResultCommand(protocolRep.executeWriter(SendfileRule.NAME, this.filename, String.valueOf(this.size), "EMPREINTEBLBLBLBLBLABLABLBALBALBALBALBALBALBALBALBALABLBALBALBALABLABLABLABLABLABLABALBLABALABLABLABLABKJABKAHBHKBHJbhjvgkh"), ResultCmdReceiver.STOREBACKEND);
} catch (IOException e) {
} catch (IOException | AES_GCM.AesGcmException e) {
this.setResultCommand(protocolRep.executeWriter(SaveFileErrorRule.NAME), ResultCmdReceiver.CLIENT);
e.printStackTrace();
}

View File

@ -36,7 +36,7 @@ public class SendfileRule extends ProtocolWriter {
public void write(OutputStream writer) {
super.write(writer);
System.out.println("Envoie du fichier au SBE");
FileSender fileSender = new FileSender("/home/benjamin/ffe");
FileSender fileSender = new FileSender("D:\\"); //"/home/benjamin/ffe");
fileSender.sendFile(hashedFileName, writer);
}
}

View File

@ -1,14 +1,21 @@
package lightcontainer.utils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
/**
* AES GCM 256 Encryption Class [DO NOT EDIT]
*
* @since 1.0
* @version 1.0
*
* @author Jérémi Nihart <contact@endmove.eu>
*/
public class AES_GCM {
// Constants
public static final int AES_KEY_SIZE = 256;
@ -17,31 +24,78 @@ public class AES_GCM {
public static void main(String[] args) throws Exception
{
// Text pour test :
String plainText = "salut fils de pute";//TODO enlever le text chelou de Jérémi (ce fou )
/*
* FILE ENCRYPTION DEMO
*/
// Init files
File inFile = new File("D:\\HELMo.png");
File outFile = new File("D:\\HELMoCrypted.png");
File clearFile = new File("D:\\HELMoClear.png");
outFile.createNewFile();
clearFile.createNewFile();
// Make options
String IVFile = generateIV();
String keyFile = generateSecretKey();
// Show options
System.out.println("IV : "+IVFile);
System.out.println("Key : "+keyFile);
// Encrypt
encryptStream(
new FileInputStream(inFile),
new FileOutputStream(outFile),
IVFile,
keyFile
);
// Decrypt
decryptStream(
new FileInputStream(outFile),
new FileOutputStream(clearFile),
IVFile,
keyFile
);
/*
* TEXT ENCRYPTION DEMO
*/
// Make option
String plainText = "Salut sombre fils de pute, comment vas tu ?";//TODO enlever le text chelou de Jérémi (ce fou )
String IV = generateIV();
String key = generateSecretKey();
System.out.println("Original Text : " + plainText);
byte[] cipherText = encrypt(plainText.getBytes(), key, IV);
System.out.println("Encrypted Text : " + Base64.getEncoder().encodeToString(cipherText));
String decryptedText = decrypt(cipherText, key, IV);
System.out.println("DeCrypted Text : " + decryptedText);
// Show options
System.out.println("IV : "+IV);
System.out.println("Key : "+key);
System.out.println("Original text : " + plainText);
// Crypt
String cryptText = encrypt(plainText, key, IV);
System.out.println("Encrypted text : " + cryptText);
// Decrypt
String decryptedText = decrypt(cryptText, key, IV);
System.out.println("Decrypted text : " + decryptedText);
}
/**
* Decoder to decode base64 vector to byte vector.
*
* @param base64Vector A base64 encoded vector.
* @return Byte vector.
*/
private static byte[] decodeBase64(String base64Vector) {
private static byte[] decodeBase64Vector(String base64Vector) {
Base64.Decoder b64Decoder = Base64.getDecoder();
return b64Decoder.decode(base64Vector);
}
/**
* Decoder to decode base64 string to plain string.
*
* @param base64String A base64 encoded string.
* @return Plain string.
*
* @see AES_GCM#decodeBase64Vector(String)
*/
private static String decodeBase64String(String base64String) {
return new String(decodeBase64Vector(base64String));
}
/**
* Encoder to encode vector to base64 string.
* @param rawVector A raw vector.
@ -53,18 +107,65 @@ public class AES_GCM {
}
/**
* Generate a secret key base64 encoded.
* @return New Secret key b64 encoded.
* Encoder to encode string to base64 string.
* @param rawString A raw string.
* @return A base64 encoded string.
*
* @see AES_GCM#encodeBase64(byte[]))
*/
public static String generateSecretKey() throws NoSuchAlgorithmException {
private static String encodeBase64(String rawString) {
return encodeBase64(rawString.getBytes(StandardCharsets.UTF_8));
}
/**
* FACTORY, to setting up a Java cryptographic cypher.
*
* @param op_mode the operation mode of this cipher (this is one of the
* following: ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE or UNWRAP_MODE)
* @param key Base64 encoded secret key.
* @param IV Base64 encoded vector.
*
* @return A Cryptography cypher.
*
* @throws AesGcmException Throw an exception in case of an error occur while setting up the the cypher.
*/
private static Cipher createCipher(int op_mode, String key, String IV) throws AesGcmException {
try {
// Get a cipher instance
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// Create a secret key from the key for the specific crypto algo
SecretKeySpec keySpec = new SecretKeySpec(decodeBase64Vector(key), "AES");
// Create a GCMParameterSpec to setting up the AES init vector
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, decodeBase64Vector(IV));
// Init the cipher for the selected operation
cipher.init(op_mode, keySpec, gcmParameterSpec);
return cipher;
} catch (InvalidAlgorithmParameterException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
throw new AesGcmException(e, "Error while creating the Cipher object");
}
}
/**
* Generate a secret key base64 encoded.
*
* @return New Secret key b64 encoded.
*
* @throws AesGcmException Exception if an error occur.
*/
public static String generateSecretKey() throws AesGcmException {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(AES_KEY_SIZE);
SecretKey key = keyGenerator.generateKey();
return encodeBase64(key.getEncoded());
} catch (NoSuchAlgorithmException e) {
throw new AesGcmException("Error while generating the AES secret key");
}
}
/**
* Generate an IV (initialisation vector) base64 encoded.
*
* @return New generated IV b64 encoded.
*/
public static String generateIV() {
@ -75,52 +176,146 @@ public class AES_GCM {
}
/**
* Encrypt, with AES GCM.
* @param plainContent Content to encrypt.
* Encrypt text, with AES GCM.
*
* @param plainText Plain text to encrypt.
* @param key Base64 encoded secret key.
* @param IV Base64 encoded vector.
* @return The encrypted cipherContent.
*
* @return The encrypted plain text Base64 encoded.
*
* @throws AesGcmException Exception if an error occur.
*/
public static byte[] encrypt(byte[] plainContent, String key, String IV) throws Exception
{
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(decodeBase64(key), "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, decodeBase64(IV));
// Initialize Cipher for ENCRYPT_MODE
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
public static String encrypt(String plainText, String key, String IV) throws AesGcmException {
try {
// Make the cipher for encryption
Cipher cipher = createCipher(Cipher.ENCRYPT_MODE, key, IV);
// Perform Encryption
return cipher.doFinal(plainContent);
return encodeBase64(cipher.doFinal(plainText.getBytes()));
} catch (Exception e) {
throw new AesGcmException(e);
}
}
/**
* Encrypt stream, with AES GCM.
*
* @param in InputStream to the input, flux to encrypt.
* @param out OutputStream to the output, encrypted flux.
* @param key Base64 encoded secret key.
* @param IV Base64 encoded vector.
*
* @throws AesGcmException Exception if an error occur.
*/
private static void encryptStream(InputStream in, OutputStream out, String key, String IV) throws AesGcmException {
byte[] buffer = new byte[1024];
int bytes;
try {
// Make the cipher for encryption
Cipher cipher = createCipher(Cipher.ENCRYPT_MODE, key, IV);
// Initialize a CipherOutputStream
CipherOutputStream cipherOut = new CipherOutputStream(out, cipher);
// Encryption Process
while((bytes = in.read(buffer)) > 0) {
cipherOut.write(buffer, 0, bytes);
cipherOut.flush();
}
// Close CipherOutputStream
cipherOut.close();
} catch (Exception e) {
throw new AesGcmException(e);
}
}
/**
* Decrypt, with AES GCM.
* @param cipherContent The encrypted cipherContent
*
* @param cryptText The encrypted text.
* @param key Base64 encoded secret key.
* @param IV Base64 encoded vector.
* @return The decrypted plainContent.
*
* @return The decrypted plain text.
*
* @throws AesGcmException Exception if an error occur.
*/
public static String decrypt(byte[] cipherContent, String key, String IV) throws Exception
{
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(decodeBase64(key), "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH*8, decodeBase64(IV));
// Initialize Cipher for DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
public static String decrypt(String cryptText, String key, String IV) throws AesGcmException {
try {
// Make the cipher for decryption
Cipher cipher = createCipher(Cipher.DECRYPT_MODE, key, IV);
// Perform Decryption
return new String(cipher.doFinal(cipherContent));
return new String(cipher.doFinal(decodeBase64Vector(cryptText)));
} catch (Exception e) {
throw new AesGcmException(e);
}
}
/**
* Decrypt stream, with AES GCM.
*
* @param in InputStream to the input, flux to decrypt.
* @param out OutputStream to the output, decrypted flux.
* @param key Base64 encoded secret key.
* @param IV Base64 encoded vector.
*
* @throws AesGcmException Exception if an error occur.
*/
private static void decryptStream(InputStream in, OutputStream out, String key, String IV) throws AesGcmException {
byte[] buffer = new byte[1024];
int bytes;
try {
// Make the cipher for decryption
Cipher cipher = createCipher(Cipher.DECRYPT_MODE, key, IV);
// Initialize a CipherOutputStream
CipherInputStream cipherIn = new CipherInputStream(in, cipher);
// Encryption Process
while((bytes = cipherIn.read(buffer)) > 0) {
out.write(buffer, 0, bytes);
out.flush();
}
// Close CipherOutputStream
cipherIn.close();
} catch (Exception e) {
throw new AesGcmException(e);
}
}
/**
* Internal Error from AES_GCM encryption Class
*/
public static class AesGcmException extends Exception {
private static final long serialVersionUID = -145972354893514657L;
/**
* Constructor of AesGcmException,
* which define it's own detail message.
*
* @param msg The detail message.
*/
public AesGcmException(String msg) {
super(msg);
}
/**
* Constructor of AesGcmException,
* which propagates the error triggering
* a crash of the encryption system.
*
* @param e Previous exception throwable.
*/
public AesGcmException(Throwable e) {
super(e);
}
/**
* Constructor of AesGcmException,
* which propagates the error triggering
* a crash of the encryption system with
* a chosen detail message.
*
* @param e Previous exception throwable.
* @param msg The detail message.
*/
public AesGcmException(GeneralSecurityException e, String msg) {
super(msg, e);
}
}
}

View File

@ -1,7 +1,9 @@
package lightcontainer.utils;
import javax.crypto.Cipher;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileReceiver {
@ -10,24 +12,19 @@ public class FileReceiver {
public FileReceiver(String path) { this.path = path; }
public boolean receiveFile(InputStream input, String fileName, long fileSize) {
public boolean receiveFile(InputStream input, String fileName, long fileSize, String key, String iv) {
int bytesReceived = 0;
BufferedOutputStream bosFile = null;
try {
byte[] buffer = new byte[DEFAULT_BUFFER];
bosFile = new BufferedOutputStream(new FileOutputStream(String.format("%s/%s", path, fileName)));
long currentOffset = 0;
while((currentOffset < fileSize) && ((bytesReceived = input.read(buffer)) > 0)) {
bosFile.write(buffer, 0, bytesReceived);
currentOffset += bytesReceived;
}
//AES_GCM.encryptStream(input, bosFile, fileSize, key, iv);
bosFile.flush();
bosFile.close();
return true;
} catch(Exception ex) {
} catch(IOException ex) {
ex.printStackTrace();
if(bosFile != null) { try { bosFile.close(); } catch(Exception e) {} }
return false;

View File

@ -10,19 +10,15 @@ public class FileSender {
public boolean sendFile(String filename, OutputStream out) {
BufferedInputStream bisFile = null;
int bytesReaded = 0;
try {
File f = new File(String.format("%s/%s", path, filename));
long fileSize = f.length();
if(f.exists()) {
byte[] buffer = new byte[DEFAULT_BUFFER];
bisFile = new BufferedInputStream(new FileInputStream(f));
long currentOffset = 0;
while((currentOffset < fileSize) && (bytesReaded = bisFile.read(buffer)) > 0) {
out.write(buffer, 0, bytesReaded); out.flush();
currentOffset+= bytesReaded;
}
//AES_GCM.encryptStream(bisFile, out, fileSize, "hyjFrdMJW6Pur8fiFueVrWKqwtnqAZmXEZPBAyBXp+o=", "e6H7xuw+PNrDppJCPLTKhg==");
bisFile.close();
return true;
} else