Добавлен разбор 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.cert.CertificateFactory;
import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey; 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.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -101,6 +103,17 @@ public class TlsDecryptor {
@SneakyThrows @SneakyThrows
private void decryptTlsRsa(String blockCipher, String hashAlgo) { 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(); Optional<RSAPublicKey> publicKeyOpt = getRsaPublicKey();
if (publicKeyOpt.isEmpty()) { if (publicKeyOpt.isEmpty()) {
@@ -128,12 +141,12 @@ public class TlsDecryptor {
TlsSecret masterSecret = preMaster.deriveUsingPRF( TlsSecret masterSecret = preMaster.deriveUsingPRF(
PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, randomCS, 48); PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, randomCS, 48);
byte[] expanded = masterSecret.deriveUsingPRF( 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[] clientMacKey = new byte[20];
byte[] serverMacKey = new byte[20]; byte[] serverMacKey = new byte[20];
byte[] clientEncryptionKey = new byte[32]; byte[] clientEncryptionKey = new byte[keyLength];
byte[] serverEncryptionKey = new byte[32]; byte[] serverEncryptionKey = new byte[keyLength];
byte[] clientIV = new byte[16]; byte[] clientIV = new byte[16];
byte[] serverIV = new byte[16]; byte[] serverIV = new byte[16];
@@ -145,8 +158,8 @@ public class TlsDecryptor {
bb.get(clientIV); bb.get(clientIV);
bb.get(serverIV); bb.get(serverIV);
Optional<Cipher> clientCipherOpt = createCipher(clientEncryptionKey, clientIV); Optional<Cipher> clientCipherOpt = createCipher(blockCipherMode, clientEncryptionKey, clientIV);
Optional<Cipher> serverCipherOpt = createCipher(serverEncryptionKey, serverIV); Optional<Cipher> serverCipherOpt = createCipher(blockCipherMode, serverEncryptionKey, serverIV);
if (clientCipherOpt.isEmpty() || serverCipherOpt.isEmpty()) { if (clientCipherOpt.isEmpty() || serverCipherOpt.isEmpty()) {
return; return;
@@ -232,8 +245,8 @@ public class TlsDecryptor {
} }
@SneakyThrows(value = {NoSuchAlgorithmException.class, NoSuchPaddingException.class}) @SneakyThrows(value = {NoSuchAlgorithmException.class, NoSuchPaddingException.class})
private Optional<Cipher> createCipher(byte[] key, byte[] iv) { private Optional<Cipher> createCipher(String mode, byte[] key, byte[] iv) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding");
SecretKeySpec serverSkeySpec = new SecretKeySpec(key, "AES"); SecretKeySpec serverSkeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec serverIvParameterSpec = new IvParameterSpec(iv); 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 WARNING = new AlertLevel((byte) 1, "warning");
public static final AlertLevel FATAL = new AlertLevel((byte) 2, "fatal"); 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) { public AlertLevel(Byte value, String name) {
super(value, name); super(value, name);
registry.put(value, this); registry.put(value, this);
} }
public static AlertLevel getInstance(Byte value) { public static AlertLevel getInstance(Byte value) {
if (registry.containsKey(value)) { return registry.getOrDefault(value, ENCRYPTED_ALERT);
return registry.get(value);
} else {
throw new IllegalArgumentException("Unknown alert level: " + value);
}
} }
@Override @Override

View File

@@ -11,6 +11,7 @@ public class AlertRecord implements TlsRecord {
private static final int LEVEL_OFFSET = 0; private static final int LEVEL_OFFSET = 0;
private static final int DESCRIPTION_OFFSET = LEVEL_OFFSET + BYTE_SIZE_IN_BYTES; private static final int DESCRIPTION_OFFSET = LEVEL_OFFSET + BYTE_SIZE_IN_BYTES;
private int length;
private AlertLevel level; private AlertLevel level;
private AlertDescription description; private AlertDescription description;
@@ -20,12 +21,20 @@ public class AlertRecord implements TlsRecord {
} }
public AlertRecord(byte[] rawData, int offset, int length) { public AlertRecord(byte[] rawData, int offset, int length) {
this.length = length;
this.level = AlertLevel.getInstance(ByteArrays.getByte(rawData, LEVEL_OFFSET + offset)); this.level = AlertLevel.getInstance(ByteArrays.getByte(rawData, LEVEL_OFFSET + offset));
if (level != AlertLevel.ENCRYPTED_ALERT) {
this.description = AlertDescription.getInstance(ByteArrays.getByte(rawData, DESCRIPTION_OFFSET + offset)); this.description = AlertDescription.getInstance(ByteArrays.getByte(rawData, DESCRIPTION_OFFSET + offset));
} }
}
@Override @Override
public String toString() { public String toString() {
if (level != AlertLevel.ENCRYPTED_ALERT) {
return " Alert [level: " + level.name() + ", description: " + description.name() + "]"; return " Alert [level: " + level.name() + ", description: " + description.name() + "]";
} else {
return " Encrypted Alert [" + length + " bytes]";
}
} }
} }