diff --git a/src/main/java/step1/Main.java b/src/main/java/step1/Main.java index 780fd33..d5181be 100644 --- a/src/main/java/step1/Main.java +++ b/src/main/java/step1/Main.java @@ -1,29 +1,129 @@ package step1; -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.*; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.ArrayList; import java.util.Base64; +import java.util.List; public class Main { + + private static final String ALGORITHM = "DESede"; + private static final String TRANSFORMATION = "DESede/CBC/PKCS5Padding"; + public static void main(String[] args){ - try(HttpClient client = HttpClient.newHttpClient()){ - String msg = "Hello !"; - byte[] encodedMsg = Base64.getEncoder().encode(msg.getBytes()); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create("http://127.0.0.1:8888")) - .POST(HttpRequest.BodyPublishers.ofByteArray(encodedMsg)) - .build(); - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + try (Socket socket = new Socket()) { + + socket.connect(new InetSocketAddress("127.0.0.1", 8888)); + + //Saving the buffer reference to read it later + BufferedReader reader = new BufferedReader( + new InputStreamReader(socket.getInputStream())); + + //Waiting for welcome message so it does + //not pollute the fucking stream + String welcome = readResponse(reader); + System.out.println("Welcome message: " + welcome); + + //Creating the key + SecretKey key = get3DESKey(); + byte[] encodedKey = key.getEncoded(); + String base64Key = Base64.getEncoder().encodeToString(encodedKey); + String formattedKey = String.format("%s\r\n", base64Key); + + //Sending the key + send(socket, formattedKey); + System.out.println("Key sent to server."); + + //Reading the message sent by the server + String text = readResponse(reader); + System.out.println("Received message: " + text); + + //Encrypting the message + String encryptedMessage = encrypt(encodedKey, text); + String base64Message = Base64.getEncoder().encodeToString(encryptedMessage.getBytes()); + System.out.println("Encrypted message to send : " + encryptedMessage); + + //Sending encrypted message + send(socket, base64Message); + System.out.println("Encrypted message sent to server."); + + //Reading the parameters sent by the server + String parameters = readResponse(reader); + System.out.println("Received parameters: " + parameters); + - System.out.println("Status code: " + response.statusCode()); - System.out.println("Response body: " + response.body()); } catch (Exception e) { - throw new RuntimeException(e); + e.printStackTrace(); } } -} + + public static void send(Socket socket, String message) throws IOException { + OutputStream output = socket.getOutputStream(); + + output.write(message.getBytes(StandardCharsets.UTF_8)); + output.flush(); + } + + public static String readResponse(BufferedReader reader) throws IOException { + return reader.readLine(); + } + + public static SecretKey get3DESKey() throws NoSuchAlgorithmException { + KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM); + keyGen.init(168); + return keyGen.generateKey(); + } + + public static String encrypt(byte[] keyBytes, String plaintext) throws Exception { + SecretKey key = new SecretKeySpec(keyBytes, ALGORITHM); + + byte[] iv = new byte[8]; + new SecureRandom().nextBytes(iv); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + + Cipher cipher = Cipher.getInstance(TRANSFORMATION); + cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); + + byte[] plaintextBytes = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] ciphertext = cipher.doFinal(plaintextBytes); + + // Prepend IV to ciphertext so receiver can extract it + byte[] ivPlusCipher = new byte[iv.length + ciphertext.length]; + System.arraycopy(iv, 0, ivPlusCipher, 0, iv.length); + System.arraycopy(ciphertext, 0, ivPlusCipher, iv.length, ciphertext.length); + + return Base64.getEncoder().encodeToString(ivPlusCipher); + } + + public static String decrypt(byte[] keyBytes, String base64IvAndCiphertext) throws Exception { + SecretKey key = new SecretKeySpec(keyBytes, ALGORITHM); + + byte[] ivPlusCipher = Base64.getDecoder().decode(base64IvAndCiphertext); + if (ivPlusCipher.length < 8) throw new IllegalArgumentException("Data too short"); + + byte[] iv = new byte[8]; + System.arraycopy(ivPlusCipher, 0, iv, 0, 8); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + + byte[] ciphertext = new byte[ivPlusCipher.length - 8]; + System.arraycopy(ivPlusCipher, 8, ciphertext, 0, ciphertext.length); + + Cipher cipher = Cipher.getInstance(TRANSFORMATION); + cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); + + byte[] plaintextBytes = cipher.doFinal(ciphertext); + return new String(plaintextBytes, StandardCharsets.UTF_8); + } + +} \ No newline at end of file