Skip to content

Instantly share code, notes, and snippets.

@benmmurphy
Last active April 30, 2024 12:11
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save benmmurphy/11349193 to your computer and use it in GitHub Desktop.
Save benmmurphy/11349193 to your computer and use it in GitHub Desktop.
SSLKEYLOGFILE for java
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.FileSystems;
import java.nio.file.StandardOpenOption;
import java.security.InvalidAlgorithmParameterException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Map;
import javax.crypto.KeyGeneratorSpi;
import javax.crypto.SecretKey;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import sun.security.internal.spec.TlsMasterSecretParameterSpec;
import com.sun.crypto.provider.TlsMasterSecretGenerator;
public class TLSLoggingProvider extends Provider{
private static FileChannel logFile;
public TLSLoggingProvider() {
super("TLSLoggingProvider", 0.1, "");
put("KeyGenerator.SunTlsMasterSecret",
MasterSecretGenerator.class.getName());
put("Alg.Alias.KeyGenerator.SunTls12MasterSecret",
"SunTlsMasterSecret");
}
private static Object getStaticField(Class c, String name) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Field f = c.getDeclaredField(name);
f.setAccessible(true);
return f.get(null);
}
public static void install() throws IOException {
String file = System.getenv("SSLKEYLOGFILE");
if (file != null) {
logFile = FileChannel.open(FileSystems.getDefault().getPath(file), StandardOpenOption.APPEND, StandardOpenOption.CREATE);
TLSLoggingProvider provider = new TLSLoggingProvider();
try {
Security.insertProviderAt(provider, 1);
Map verified = (Map)getStaticField(Class.forName("javax.crypto.JceSecurity"), "verificationResults");
verified.put(provider, Boolean.TRUE);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) throws Exception {
install();
SSLSocket socket = (SSLSocket)SSLSocketFactory.getDefault().createSocket("62.252.169.167", 443);
socket.startHandshake();
socket.getOutputStream().write("GET / HTTP/1.1\r\nHost:google.com\r\n\r\n".getBytes("UTF-8"));
socket.getOutputStream().flush();
socket.getInputStream().read();
}
public static class MasterSecretGenerator extends KeyGeneratorSpi {
private KeyGeneratorSpi delegate;
private TlsMasterSecretParameterSpec spec;
public MasterSecretGenerator() {
this.delegate = new TlsMasterSecretGenerator();
}
private Object invoke(Object o, String method) {
try {
Method m = o.getClass().getDeclaredMethod(method);
m.setAccessible(true);
return m.invoke(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object invoke(Object o, String method, Class[] types, Object... args) {
try {
Method m = o.getClass().getDeclaredMethod(method, types);
m.setAccessible(true);
return m.invoke(o, args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
@Override
protected SecretKey engineGenerateKey() {
SecretKey secret = (SecretKey)invoke(delegate, "engineGenerateKey");
String entry = "CLIENT_RANDOM " + bytesToHex(spec.getClientRandom()) + " " + bytesToHex(secret.getEncoded()) + "\n";
try {
logFile.write(ByteBuffer.wrap(entry.getBytes("ASCII")));
} catch (IOException e) {
e.printStackTrace();
}
return secret;
}
@Override
protected void engineInit(SecureRandom arg0) {
invoke(delegate, "engineInit", new Class[]{SecureRandom.class}, arg0);
}
@Override
protected void engineInit(AlgorithmParameterSpec arg0, SecureRandom arg1)
throws InvalidAlgorithmParameterException {
this.spec = (TlsMasterSecretParameterSpec)arg0;
invoke(delegate, "engineInit", new Class[]{AlgorithmParameterSpec.class, SecureRandom.class}, spec, arg1);
}
@Override
protected void engineInit(int arg0, SecureRandom arg1) {
invoke(delegate, "engineInit", new Class[]{int.class, SecureRandom.class}, arg0, arg1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment