From 98735032c81244692d90fd0118df75d6de251649 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Fri, 8 May 2020 22:45:12 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=20TLS=20=D1=81=20?= =?UTF-8?q?AES128?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 29 ++++++++++++++----- .../optimization/tls/numbers/AlertLevel.java | 8 ++--- .../optimization/tls/records/AlertRecord.java | 13 +++++++-- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 6390b66..e492285 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -40,7 +40,9 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -101,6 +103,17 @@ public class TlsDecryptor { @SneakyThrows private void decryptTlsRsa(String blockCipher, String hashAlgo) { + String[] blockCipherParts = blockCipher.split("_"); + String blockCipherAlgo = blockCipherParts[0]; + int blockCipherSize = Integer.parseInt(blockCipherParts[1]); + String blockCipherMode = blockCipherParts[2]; + + if (!blockCipherAlgo.equals("AES")) { + return; + } + + int keyLength = blockCipherSize / 8; + Optional publicKeyOpt = getRsaPublicKey(); if (publicKeyOpt.isEmpty()) { @@ -128,12 +141,12 @@ public class TlsDecryptor { TlsSecret masterSecret = preMaster.deriveUsingPRF( PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, randomCS, 48); byte[] expanded = masterSecret.deriveUsingPRF( - PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 136).extract(); // для sha256 + PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 72 + keyLength * 2).extract(); // для sha256 byte[] clientMacKey = new byte[20]; byte[] serverMacKey = new byte[20]; - byte[] clientEncryptionKey = new byte[32]; - byte[] serverEncryptionKey = new byte[32]; + byte[] clientEncryptionKey = new byte[keyLength]; + byte[] serverEncryptionKey = new byte[keyLength]; byte[] clientIV = new byte[16]; byte[] serverIV = new byte[16]; @@ -145,8 +158,8 @@ public class TlsDecryptor { bb.get(clientIV); bb.get(serverIV); - Optional clientCipherOpt = createCipher(clientEncryptionKey, clientIV); - Optional serverCipherOpt = createCipher(serverEncryptionKey, serverIV); + Optional clientCipherOpt = createCipher(blockCipherMode, clientEncryptionKey, clientIV); + Optional serverCipherOpt = createCipher(blockCipherMode, serverEncryptionKey, serverIV); if (clientCipherOpt.isEmpty() || serverCipherOpt.isEmpty()) { return; @@ -232,8 +245,8 @@ public class TlsDecryptor { } @SneakyThrows(value = {NoSuchAlgorithmException.class, NoSuchPaddingException.class}) - private Optional createCipher(byte[] key, byte[] iv) { - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA + private Optional createCipher(String mode, byte[] key, byte[] iv) { + Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding"); SecretKeySpec serverSkeySpec = new SecretKeySpec(key, "AES"); IvParameterSpec serverIvParameterSpec = new IvParameterSpec(iv); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertLevel.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertLevel.java index 1f2c069..e33f489 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertLevel.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertLevel.java @@ -13,17 +13,15 @@ public class AlertLevel extends NamedNumber { public static final AlertLevel WARNING = new AlertLevel((byte) 1, "warning"); public static final AlertLevel FATAL = new AlertLevel((byte) 2, "fatal"); + public static final AlertLevel ENCRYPTED_ALERT = new AlertLevel((byte) 0, "encrypted alert"); + public AlertLevel(Byte value, String name) { super(value, name); registry.put(value, this); } public static AlertLevel getInstance(Byte value) { - if (registry.containsKey(value)) { - return registry.get(value); - } else { - throw new IllegalArgumentException("Unknown alert level: " + value); - } + return registry.getOrDefault(value, ENCRYPTED_ALERT); } @Override diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/AlertRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/AlertRecord.java index e902c19..df746e9 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/AlertRecord.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/AlertRecord.java @@ -11,6 +11,7 @@ public class AlertRecord implements TlsRecord { private static final int LEVEL_OFFSET = 0; private static final int DESCRIPTION_OFFSET = LEVEL_OFFSET + BYTE_SIZE_IN_BYTES; + private int length; private AlertLevel level; private AlertDescription description; @@ -20,12 +21,20 @@ public class AlertRecord implements TlsRecord { } public AlertRecord(byte[] rawData, int offset, int length) { + this.length = length; this.level = AlertLevel.getInstance(ByteArrays.getByte(rawData, LEVEL_OFFSET + offset)); - this.description = AlertDescription.getInstance(ByteArrays.getByte(rawData, DESCRIPTION_OFFSET + offset)); + + if (level != AlertLevel.ENCRYPTED_ALERT) { + this.description = AlertDescription.getInstance(ByteArrays.getByte(rawData, DESCRIPTION_OFFSET + offset)); + } } @Override public String toString() { - return " Alert [level: " + level.name() + ", description: " + description.name() + "]"; + if (level != AlertLevel.ENCRYPTED_ALERT) { + return " Alert [level: " + level.name() + ", description: " + description.name() + "]"; + } else { + return " Encrypted Alert [" + length + " bytes]"; + } } }