Работа над расшифровкой TLS

This commit is contained in:
serega6531
2020-04-25 03:14:59 +03:00
parent 441e210ea7
commit fd50fff1a2
12 changed files with 206 additions and 148 deletions

28
rsa_keys/example.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDWJO65om/5LMA0
8w9Uk36h4ukQ7Qt8nbpbeHzxorl4lGwWBASEAEmDYNUcGO0CxglOE93F9BPNGn6q
Vj8Ypp3kcTGOzsXcFrd0wRpXbSwbynnmqTCYigiLzIidasfUrGul4s1fVZFdkQZS
p2Y5pEUxq1GKcAgCVwjMyWC1dhGqvTcA5ps0JoSRoA+Nzs/BeTHlTm8UvT9eD9ER
8RmYVOi1edcJ/eztj1CVydq5X27QNmwLuqsAwq38I27nlq1NU5ShqDQ16bg8IY/c
Ll4QJB7SVbrLf3dJ7KY5i7DNEoYUiJGRwDJZt+wcZLtFSzj0cn0BuEU6M0PYglUI
uQTeosUZAgMBAAECggEAehq7CJyHzoPm4QpLDoW/qh1RmfYgG6FwVqHgVIPdz9SJ
wQ/vZzkmscPwIEJSOsejHKMVTL983vGhkgz1k1/GHjEw+eYLShCl8Ov+0iUNBpew
ZIbKj9/9OYGZ0HDHmwvpocAuLJME/V4pRc3v6yQw1D6EkzSITJVGDkcxXqcBMeIA
uNVr+pwLH9vO7ybva+e3T4ROWxlecHrcB94THops4fy5+SGVILwvKaP4cRhjLfD4
2XV4O5N0imdPAYsNNHyHbAzjvZPoCOsuH3B/tWmRHq3oOa4ZcFUNTDmO9GgfbtY/
PHEFV34XxMjy3bK0vLxHqS9CEj1cvfq8e1NqkDTugQKBgQD6CEezGf9OFb3byBui
X3OzXWdWQ5jnodOTPb/P+y9DrORJPy1/0BcXh/cHF58kNDZvzVwTFcAjfx6bxS41
JAddFRZjNuHXEOtFRkD3Wp4W7Atrv/yeKbpE9PCaNYtUDasL8RKcdJiHNFpN4xRl
jpQtIiQ9pikrjUXLgW0S88zzyQKBgQDbQV+DMxGS2Cee6nfMmUcGjgQd8D0cXLjk
OZSmEnk4FCvV8ZdysjirqmuitFTE+PYmOJzhlQl8lubEs4Kc7L9CfEwbK9mNN0ZG
BNdT21nFuJp7YoZzZDTHuwF0nBjQFYcdaWDW+qFqrqs9mKbmCQ5vSzql6al+pzdX
X/YS0QTO0QKBgDUMprHQdUPLByJnnb1gxTqsOa2q3/ldc3eNJXJqWAfi2fjUh8HT
k+KxPW9qyqAy1832429FMSQW55ajSn+J6moMfFiGn3ozI8fp9QTGXD5+zJmK/X1N
WzEgSyBc9ffago0hFBLQBkDBkdtur7gwfS3qTYgrBhcwfTuFdXAM/FJJAoGABIQ2
OXel1waI2mcuDJLjuajXQN6gA6ONU3Y0L6+Vu6f+tyuA2SX+sNqT2Qgp7tzKBUOJ
R8RQK7bYDhk8iYr+7Zmt36lpk9Udp3eWD+4mzUHePMhsyJe51pttjj9g63hmDh8L
laIYDSCH+n7YgUiSeYxtKtnDWg6Lv0sEwKJ5nOECgYBsF5PoHRE4Q/Vs18qbI4t/
zPwWWNP0sb3PYRlWLTKMBowQdDOxnXAF12txoLNhpOn9DjZdNEb2EMsqlzdNjphN
uUWZq89d5kDwKfj4ji087elcjsW79R5oqwrN8a0NimftZ4eBPbcn8Y0r5psPcSzE
36iKGM2euQYD8Ub+aDOSLQ==
-----END PRIVATE KEY-----

View File

@@ -55,6 +55,8 @@ public class Packet {
private boolean webSocketParsed; private boolean webSocketParsed;
private boolean tlsDecrypted;
private byte[] content; private byte[] content;
@Transient @Transient

View File

@@ -137,6 +137,7 @@ public class HttpChunksProcessor {
.timestamp(packets.get(0).getTimestamp()) .timestamp(packets.get(0).getTimestamp())
.ungzipped(false) .ungzipped(false)
.webSocketParsed(false) .webSocketParsed(false)
.tlsDecrypted(packets.get(0).isTlsDecrypted())
.content(output.toByteArray()) .content(output.toByteArray())
.build(); .build();

View File

@@ -105,6 +105,7 @@ public class HttpGzipProcessor {
.timestamp(cut.get(0).getTimestamp()) .timestamp(cut.get(0).getTimestamp())
.ungzipped(true) .ungzipped(true)
.webSocketParsed(false) .webSocketParsed(false)
.tlsDecrypted(cut.get(0).isTlsDecrypted())
.content(newContent) .content(newContent)
.build(); .build();
} catch (ZipException e) { } catch (ZipException e) {

View File

@@ -50,7 +50,8 @@ public class PacketsMerger {
final long timestamp = cut.get(0).getTimestamp(); final long timestamp = cut.get(0).getTimestamp();
final boolean ungzipped = cut.stream().anyMatch(Packet::isUngzipped); final boolean ungzipped = cut.stream().anyMatch(Packet::isUngzipped);
final boolean webSocketParsed = cut.stream().anyMatch(Packet::isWebSocketParsed); final boolean webSocketParsed = cut.stream().anyMatch(Packet::isWebSocketParsed);
boolean incoming = cut.get(0).isIncoming(); final boolean tlsDecrypted = cut.get(0).isTlsDecrypted();
final boolean incoming = cut.get(0).isIncoming();
//noinspection OptionalGetWithoutIsPresent //noinspection OptionalGetWithoutIsPresent
final byte[] content = PacketUtils.mergePackets(cut).get(); final byte[] content = PacketUtils.mergePackets(cut).get();
@@ -60,6 +61,7 @@ public class PacketsMerger {
.timestamp(timestamp) .timestamp(timestamp)
.ungzipped(ungzipped) .ungzipped(ungzipped)
.webSocketParsed(webSocketParsed) .webSocketParsed(webSocketParsed)
.tlsDecrypted(tlsDecrypted)
.content(content) .content(content)
.build()); .build());
} }

View File

@@ -1,41 +1,74 @@
package ru.serega6531.packmate.service.optimization; package ru.serega6531.packmate.service.optimization;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.serega6531.packmate.utils.TlsUtils;
import javax.net.ssl.X509KeyManager;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.file.Files;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
@Service @Service
@Slf4j
public class RsaKeysHolder { public class RsaKeysHolder {
// Key: N from RSA public key // Key: N from RSA public key
private final Map<BigInteger, RSAPrivateKey> keys = new HashMap<>(); private final Map<BigInteger, RSAPrivateKey> keys = new HashMap<>();
public void addKey(File pemFile, File keyFile) {
if(!pemFile.exists() || !keyFile.exists()) {
throw new IllegalArgumentException("One of files does not exist");
}
X509KeyManager keyManager = TlsUtils.createKeyManager(pemFile, keyFile);
RSAPrivateKey privateKey = ((RSAPrivateKey) keyManager.getPrivateKey("1"));
keys.put(privateKey.getModulus(), privateKey);
}
public RSAPrivateKey getKey(BigInteger modulus) { public RSAPrivateKey getKey(BigInteger modulus) {
return keys.get(modulus); return keys.get(modulus);
} }
@EventListener(ApplicationReadyEvent.class) @EventListener(ApplicationReadyEvent.class)
public void afterStartup(ApplicationReadyEvent event) { public void afterStartup(ApplicationReadyEvent event) {
//TODO load keys File dir = new File("rsa_keys");
if (dir.exists() && dir.isDirectory()) {
for (File keyFile : Objects.requireNonNull(dir.listFiles())) {
addKey(keyFile);
}
}
}
@SneakyThrows
public void addKey(File keyFile) {
if (!keyFile.exists()) {
throw new IllegalArgumentException("Key file does not exist");
}
try {
RSAPrivateKey privateKey = loadFromFile(keyFile);
keys.put(privateKey.getModulus(), privateKey);
String n = privateKey.getModulus().toString();
log.info("Loaded RSA key with N={}...", n.substring(0, Math.min(n.length(), 8)));
} catch (IOException | InvalidKeySpecException e) {
log.error("Error loading rsa key", e);
}
}
private RSAPrivateKey loadFromFile(File keyFile) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
String content = Files.readString(keyFile.toPath());
content = content.replaceAll("-----BEGIN (RSA )?PRIVATE KEY-----", "")
.replaceAll("-----END (RSA )?PRIVATE KEY-----", "")
.replace("\n", "");
byte[] keyBytes = Base64.getDecoder().decode(content);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return (RSAPrivateKey) kf.generatePrivate(spec);
} }
} }

View File

@@ -49,7 +49,11 @@ public class StreamOptimizer {
private void decryptTls() { private void decryptTls() {
final TlsDecryptor tlsDecryptor = new TlsDecryptor(packets, keysHolder); final TlsDecryptor tlsDecryptor = new TlsDecryptor(packets, keysHolder);
tlsDecryptor.decryptTls(); // TODO tlsDecryptor.decryptTls();
if(tlsDecryptor.isParsed()) {
packets = tlsDecryptor.getParsedPackets();
}
} }
/** /**

View File

@@ -2,6 +2,7 @@ package ru.serega6531.packmate.service.optimization;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap; import com.google.common.collect.ListMultimap;
import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -22,12 +23,18 @@ import ru.serega6531.packmate.service.optimization.tls.records.ApplicationDataRe
import ru.serega6531.packmate.service.optimization.tls.records.HandshakeRecord; import ru.serega6531.packmate.service.optimization.tls.records.HandshakeRecord;
import ru.serega6531.packmate.service.optimization.tls.records.handshakes.*; import ru.serega6531.packmate.service.optimization.tls.records.handshakes.*;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
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;
@@ -45,10 +52,18 @@ public class TlsDecryptor {
private final List<Packet> packets; private final List<Packet> packets;
private final RsaKeysHolder keysHolder; private final RsaKeysHolder keysHolder;
@Getter
private boolean parsed = false;
private List<Packet> result;
private ListMultimap<Packet, TlsPacket.TlsHeader> tlsPackets;
private CipherSuite cipherSuite;
private byte[] clientRandom;
private byte[] serverRandom;
@SneakyThrows @SneakyThrows
public void decryptTls() { public void decryptTls() {
ListMultimap<Packet, TlsPacket.TlsHeader> tlsPackets = ArrayListMultimap.create(packets.size(), 1); tlsPackets = ArrayListMultimap.create(packets.size(), 1);
packets.forEach(p -> tlsPackets.putAll(p, createTlsHeaders(p))); packets.forEach(p -> tlsPackets.putAll(p, createTlsHeaders(p)));
var clientHello = (ClientHelloHandshakeRecordContent) var clientHello = (ClientHelloHandshakeRecordContent)
@@ -56,10 +71,7 @@ public class TlsDecryptor {
var serverHello = (ServerHelloHandshakeRecordContent) var serverHello = (ServerHelloHandshakeRecordContent)
getHandshake(tlsPackets.values(), HandshakeType.SERVER_HELLO).orElseThrow(); getHandshake(tlsPackets.values(), HandshakeType.SERVER_HELLO).orElseThrow();
byte[] clientRandom = clientHello.getRandom(); cipherSuite = serverHello.getCipherSuite();
byte[] serverRandom = serverHello.getRandom();
CipherSuite cipherSuite = serverHello.getCipherSuite();
if (cipherSuite.name().startsWith("TLS_RSA_WITH_")) { if (cipherSuite.name().startsWith("TLS_RSA_WITH_")) {
Matcher matcher = cipherSuitePattern.matcher(cipherSuite.name()); Matcher matcher = cipherSuitePattern.matcher(cipherSuite.name());
@@ -68,33 +80,34 @@ public class TlsDecryptor {
String blockCipher = matcher.group(1); //TODO использовать не только AES256 String blockCipher = matcher.group(1); //TODO использовать не только AES256
String hashAlgo = matcher.group(2); String hashAlgo = matcher.group(2);
var certificateHandshake = ((CertificateHandshakeRecordContent) clientRandom = clientHello.getRandom();
getHandshake(tlsPackets.values(), HandshakeType.CERTIFICATE).orElseThrow()); serverRandom = serverHello.getRandom();
List<byte[]> chain = certificateHandshake.getRawCertificates();
byte[] rawCertificate = chain.get(0);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(rawCertificate));
RSAPublicKey publicKey = (RSAPublicKey) certificate.getPublicKey();
decryptTlsRsa(blockCipher, hashAlgo);
}
}
private void decryptTlsRsa(String blockCipher, String hashAlgo) throws CertificateException, NoSuchPaddingException, NoSuchAlgorithmException {
RSAPublicKey publicKey = getRsaPublicKey();
RSAPrivateKey privateKey = keysHolder.getKey(publicKey.getModulus()); RSAPrivateKey privateKey = keysHolder.getKey(publicKey.getModulus());
if(privateKey == null) { if (privateKey == null) {
log.warn("Key for modulus not found: {}", publicKey.getModulus()); String n = publicKey.getModulus().toString();
log.warn("Key for modulus not found: {}...", n.substring(0, Math.min(n.length(), 8)));
return; return;
} }
var clientKeyExchange = (BasicHandshakeRecordContent) BcTlsSecret preMaster;
getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow(); try {
preMaster = getPreMaster(privateKey);
} catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
log.warn("Failed do get pre-master key", e);
return;
}
byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0);
Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsa.init(Cipher.DECRYPT_MODE, privateKey);
byte[] preMaster = rsa.doFinal(encryptedPreMaster);
byte[] randomCS = ArrayUtils.addAll(clientRandom, serverRandom); byte[] randomCS = ArrayUtils.addAll(clientRandom, serverRandom);
byte[] randomSC = ArrayUtils.addAll(serverRandom, clientRandom); byte[] randomSC = ArrayUtils.addAll(serverRandom, clientRandom);
BcTlsSecret preSecret = new BcTlsSecret(new BcTlsCrypto(null), preMaster); TlsSecret masterSecret = preMaster.deriveUsingPRF(
TlsSecret masterSecret = preSecret.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, 136).extract(); // для sha256
@@ -120,8 +133,10 @@ public class TlsDecryptor {
Cipher clientCipher = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted); Cipher clientCipher = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted);
Cipher serverCipher = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted); Cipher serverCipher = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted);
result = new ArrayList<>(packets.size());
for (Packet packet : packets) { for (Packet packet : packets) {
List<TlsPacket.TlsHeader> tlsData = (List<TlsPacket.TlsHeader>) tlsPackets.get(packet); List<TlsPacket.TlsHeader> tlsData = tlsPackets.get(packet);
for (TlsPacket.TlsHeader tlsPacket : tlsData) { for (TlsPacket.TlsHeader tlsPacket : tlsData) {
if (tlsPacket.getContentType() == ContentType.APPLICATION_DATA) { if (tlsPacket.getContentType() == ContentType.APPLICATION_DATA) {
@@ -130,20 +145,50 @@ public class TlsDecryptor {
byte[] decoded; byte[] decoded;
if(client) { if (client) {
decoded = clientCipher.update(data); decoded = clientCipher.update(data);
} else { } else {
decoded = serverCipher.update(data); decoded = serverCipher.update(data);
} }
decoded = clearDecodedData(decoded); decoded = clearDecodedData(decoded);
String string = new String(decoded);
log.info(string); result.add(Packet.builder()
} .content(decoded)
.incoming(packet.isIncoming())
.timestamp(packet.getTimestamp())
.ungzipped(false)
.webSocketParsed(false)
.tlsDecrypted(true)
.ttl(packet.getTtl())
.build());
} }
} }
} }
parsed = true;
}
private BcTlsSecret getPreMaster(RSAPrivateKey privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
var clientKeyExchange = (BasicHandshakeRecordContent)
getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow();
byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0);
Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsa.init(Cipher.DECRYPT_MODE, privateKey);
byte[] preMaster = rsa.doFinal(encryptedPreMaster);
return new BcTlsSecret(new BcTlsCrypto(null), preMaster);
}
private RSAPublicKey getRsaPublicKey() throws CertificateException {
var certificateHandshake = ((CertificateHandshakeRecordContent)
getHandshake(tlsPackets.values(), HandshakeType.CERTIFICATE).orElseThrow());
List<byte[]> chain = certificateHandshake.getRawCertificates();
byte[] rawCertificate = chain.get(0);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(rawCertificate));
return (RSAPublicKey) certificate.getPublicKey();
} }
@SneakyThrows @SneakyThrows
@@ -206,4 +251,12 @@ public class TlsDecryptor {
return headers; return headers;
} }
public List<Packet> getParsedPackets() {
if (!parsed) {
throw new IllegalStateException("TLS is not parsed");
}
return result;
}
} }

View File

@@ -132,6 +132,7 @@ public class WebSocketsParser {
.ttl(lastPacket.getTtl()) .ttl(lastPacket.getTtl())
.ungzipped(lastPacket.isUngzipped()) .ungzipped(lastPacket.isUngzipped())
.webSocketParsed(true) .webSocketParsed(true)
.tlsDecrypted(lastPacket.isTlsDecrypted())
.build() .build()
); );
} }

View File

@@ -1,47 +0,0 @@
package ru.serega6531.packmate.utils;
import com.google.common.base.Splitter;
import lombok.SneakyThrows;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.X509KeyManager;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import static com.google.common.base.Preconditions.checkState;
public class TlsUtils {
@SneakyThrows
public static X509KeyManager createKeyManager(File pemFile, File keyFile) {
final String pass = "abcdef";
File jksKeystoreFile = File.createTempFile("packmate_", ".jks");
File pkcsKeystoreFile = File.createTempFile("packmate_", ".pkcs12");
Splitter splitter = Splitter.on(' ');
jksKeystoreFile.delete();
String command = "openssl pkcs12 -export -out " + pkcsKeystoreFile.getAbsolutePath() + " -in " + pemFile.getAbsolutePath() +
" -inkey " + keyFile.getAbsolutePath() + " -passout pass:" + pass;
Process process = new ProcessBuilder(splitter.splitToList(command)).inheritIO().start();
checkState(process.waitFor() == 0);
command = "keytool -importkeystore -srckeystore " + pkcsKeystoreFile.getAbsolutePath() + " -srcstoretype PKCS12 -destkeystore " +
jksKeystoreFile.getAbsolutePath() + " -srcstorepass " + pass + " -deststorepass " + pass;
process = new ProcessBuilder(splitter.splitToList(command)).inheritIO().start();
checkState(process.waitFor() == 0);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(new FileInputStream(jksKeystoreFile), pass.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore, pass.toCharArray());
return (X509KeyManager) keyManagerFactory.getKeyManagers()[0];
}
}

View File

@@ -16,9 +16,8 @@ public class TlsDecryptorTest {
List<Packet> packets = new PackmateDumpFileLoader("tls.pkmt").getPackets(); List<Packet> packets = new PackmateDumpFileLoader("tls.pkmt").getPackets();
RsaKeysHolder keysHolder = new RsaKeysHolder(); RsaKeysHolder keysHolder = new RsaKeysHolder();
File pemFile = new File(getClass().getClassLoader().getResource("tls.pem").getFile());
File keyFile = new File(getClass().getClassLoader().getResource("tls.key").getFile()); File keyFile = new File(getClass().getClassLoader().getResource("tls.key").getFile());
keysHolder.addKey(pemFile, keyFile); keysHolder.addKey(keyFile);
TlsDecryptor decryptor = new TlsDecryptor(packets, keysHolder); TlsDecryptor decryptor = new TlsDecryptor(packets, keysHolder);
decryptor.decryptTls(); decryptor.decryptTls();

View File

@@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIUP8G0cbkVa5e5XMfhm0ewi9FKmVgwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMDQxNzEzMjEyNVoXDTIxMDQx
NzEzMjEyNVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA1iTuuaJv+SzANPMPVJN+oeLpEO0LfJ26W3h88aK5eJRs
FgQEhABJg2DVHBjtAsYJThPdxfQTzRp+qlY/GKad5HExjs7F3Ba3dMEaV20sG8p5
5qkwmIoIi8yInWrH1KxrpeLNX1WRXZEGUqdmOaRFMatRinAIAlcIzMlgtXYRqr03
AOabNCaEkaAPjc7PwXkx5U5vFL0/Xg/REfEZmFTotXnXCf3s7Y9QlcnauV9u0DZs
C7qrAMKt/CNu55atTVOUoag0Nem4PCGP3C5eECQe0lW6y393SeymOYuwzRKGFIiR
kcAyWbfsHGS7RUs49HJ9AbhFOjND2IJVCLkE3qLFGQIDAQABo1MwUTAdBgNVHQ4E
FgQU2nillgHV/VxE0Rf5sVlNbEogs8cwHwYDVR0jBBgwFoAU2nillgHV/VxE0Rf5
sVlNbEogs8cwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAg287
XL7cBkT3WlR4Mxocg2k7khBfhUGTU5Y9HbZcsV83vkjY6Q2zRhtB1kwNBO/KPOE+
+TUPgO9cL6wBk1QZISxUzEl1AvNxZOqUqZUubRKMzeAzoVF+ItkRxiXrQe80RVY3
IjEpdajqBKOeEg6n3/5COh3UnvcdHaFsnbCspSfAUYUO9J0s6hLPHIJVSaqEfO9p
eW2I9vUu7HnzM8bvawwzciFV0v5DrO6/2TbbfiGCYdsebsZD1QAzsWu2KTFmjGWo
pDXWcd+h7oeKTGYvRtSEU/g/IMttH6HrT/N1tpBpv9GG7FLRsICgEzcpgAmvfR7a
tg5VUZwbxAXLxKSjjw==
-----END CERTIFICATE-----