Добавлен разбор TLS с AES128

This commit is contained in:
serega6531
2020-05-08 22:45:12 +03:00
parent 49dcd974bc
commit 98735032c8
3 changed files with 35 additions and 15 deletions

View File

@@ -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<RSAPublicKey> 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<Cipher> clientCipherOpt = createCipher(clientEncryptionKey, clientIV);
Optional<Cipher> serverCipherOpt = createCipher(serverEncryptionKey, serverIV);
Optional<Cipher> clientCipherOpt = createCipher(blockCipherMode, clientEncryptionKey, clientIV);
Optional<Cipher> 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<Cipher> createCipher(byte[] key, byte[] iv) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA
private Optional<Cipher> 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);

View File

@@ -13,17 +13,15 @@ public class AlertLevel extends NamedNumber<Byte, AlertLevel> {
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

View File

@@ -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]";
}
}
}