Packet Capture v1.4.7版本的 MD5 值为:edce2fbbf748df1d1d0ca3d6f00c9bc3

以下内容为反编译后的 CACertGenerator.java 源代码,内容仅作参考


package app.ssldecryptor;

import android.content.Context;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import kotlin.TypeCastException;
import kotlin.jvm.internal.Intrinsics;
import org.spongycastle.asn1.x500.X500Name;
import org.spongycastle.asn1.x509.BasicConstraints;
import org.spongycastle.asn1.x509.ExtendedKeyUsage;
import org.spongycastle.asn1.x509.GeneralName;
import org.spongycastle.asn1.x509.GeneralNames;
import org.spongycastle.asn1.x509.KeyPurposeId;
import org.spongycastle.asn1.x509.KeyUsage;
import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
import org.spongycastle.asn1.x509.X509Extensions;
import org.spongycastle.cert.X509v3CertificateBuilder;
import org.spongycastle.cert.jcajce.JcaX509CertificateConverter;
import org.spongycastle.operator.ContentSigner;
import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;

public final class CACertGenerator {
    private static final String BC = "SC";
    public static final CACertGenerator INSTANCE = null;
    private static long ONEYEAR_IN_MS;

    static {
        new CACertGenerator();
    }

    private CACertGenerator() {
        INSTANCE = this;
        ONEYEAR_IN_MS = 31536000000L;
        BC = BC;
    }

    public final String makeStoreFileName(Context context) {
        Intrinsics.checkParameterIsNotNull(context, "context");
        File file = new File(context.getFilesDir(), "castore");
        return file.getAbsolutePath();
    }

    public final CertKeyStore generateFsCertStore(Context context) {
        Intrinsics.checkParameterIsNotNull(context, "context");
        String storeFileName = makeStoreFileName(context);
        if (storeFileName == null) {
            return null;
        }
        try {
            CertKeyStore generate = generate(storeFileName);
            ProxyCertCache.INSTANCE.clear();
            return generate;
        } catch (Exception e) {
            return null;
        }
    }

    public final CertKeyStore loadCert(Context context) {
        CertKeyStore fsCert;
        Intrinsics.checkParameterIsNotNull(context, "context");
        String storeFileName = makeStoreFileName(context);
        if (storeFileName == null || (fsCert = loadFsCert(storeFileName)) == null) {
            return null;
        }
        return fsCert;
    }

    public final void save(Context context, PrivateKey privKey, X509Certificate cert) {
        Intrinsics.checkParameterIsNotNull(context, "context");
        Intrinsics.checkParameterIsNotNull(privKey, "privKey");
        Intrinsics.checkParameterIsNotNull(cert, "cert");
        String storeFileName = makeStoreFileName(context);
        if (storeFileName != null) {
            char[] charArray = "password".toCharArray();
            Intrinsics.checkExpressionValueIsNotNull(charArray, "(this as java.lang.String).toCharArray()");
            char[] charArray2 = "keypass".toCharArray();
            Intrinsics.checkExpressionValueIsNotNull(charArray2, "(this as java.lang.String).toCharArray()");
            save(storeFileName, charArray, "alias", charArray2, privKey, cert);
        }
    }

    public final boolean isCertInstalled(CertKeyStore fsCert) {
        Intrinsics.checkParameterIsNotNull(fsCert, "fsCert");
        KeyStore ks = KeyStore.getInstance("AndroidCAStore");
        ks.load(null, null);
        Enumeration e = ks.aliases();
        while (e.hasMoreElements()) {
            String alias = e.nextElement();
            Certificate installedCert = ks.getCertificate(alias);
            if (installedCert != null && (installedCert instanceof X509Certificate)) {
                Log.i("SSL", alias);
                Log.i("SSL", ((X509Certificate) installedCert).getSubjectDN().getName());
                Log.i("SSL", ((X509Certificate) installedCert).getSubjectX500Principal().getName());
                if (Arrays.equals(((X509Certificate) installedCert).getSignature(), fsCert.getCert().getSignature())) {
                    Log.i("SSL", "signature match");
                    return true;
                }
            }
        }
        Log.i("SSL", "no matching signagure");
        return false;
    }

    public final CertKeyStore loadOrGenerate(Context context) {
        Intrinsics.checkParameterIsNotNull(context, "context");
        String storeFileName = makeStoreFileName(context);
        if (storeFileName == null) {
            return null;
        }
        CertKeyStore loaded = loadFsCert(storeFileName);
        if (loaded == null) {
            CertKeyStore generated = generate(storeFileName);
            ProxyCertCache.INSTANCE.clear();
            return generated;
        }
        return loaded;
    }

    private final CertKeyStore loadFsCert(String storeFileName) {
        FileInputStream fin;
        PrivateKey privKey;
        Certificate certificate;
        CertKeyStore certKeyStore = null;
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream fin2 = (FileInputStream) null;
        try {
            try {
                fin = new FileInputStream(storeFileName);
                if (keyStore == null) {
                    try {
                        Intrinsics.throwNpe();
                    } catch (Exception e) {
                        e = e;
                        fin2 = fin;
                        System.out.printf("store load error %s\n", e.toString());
                        if (fin2 != null) {
                            try {
                                fin2.close();
                            } catch (IOException e2) {
                            }
                        }
                        return certKeyStore;
                    } catch (Throwable th) {
                        th = th;
                        fin2 = fin;
                        if (fin2 != null) {
                            try {
                                fin2.close();
                            } catch (IOException e3) {
                            }
                        }
                        throw th;
                    }
                }
                char[] charArray = "password".toCharArray();
                Intrinsics.checkExpressionValueIsNotNull(charArray, "(this as java.lang.String).toCharArray()");
                keyStore.load(fin, charArray);
                char[] charArray2 = "keypass".toCharArray();
                Intrinsics.checkExpressionValueIsNotNull(charArray2, "(this as java.lang.String).toCharArray()");
                privKey = (PrivateKey) keyStore.getKey("alias", charArray2);
                certificate = keyStore.getCertificate("alias");
            } catch (Throwable th2) {
                th = th2;
            }
        } catch (Exception e4) {
            e = e4;
        }
        if (certificate == null) {
            throw new TypeCastException("null cannot be cast to non-null type java.security.cert.X509Certificate");
        }
        X509Certificate cert = (X509Certificate) certificate;
        try {
            fin.close();
        } catch (IOException e5) {
        }
        if (keyStore == null || privKey == null || cert == null) {
            fin2 = fin;
        } else {
            char[] charArray3 = "password".toCharArray();
            Intrinsics.checkExpressionValueIsNotNull(charArray3, "(this as java.lang.String).toCharArray()");
            certKeyStore = new CertKeyStore(keyStore, charArray3, cert, privKey);
            fin2 = fin;
        }
        return certKeyStore;
    }

    private final CertKeyStore generate(String storeFileName) {
        try {
            KeyPair pair = generateRSAKeyPair();
            PrivateKey privKey = pair.getPrivate();
            X509Certificate cert = generateV3Certificate(pair);
            cert.checkValidity(new Date());
            cert.verify(cert.getPublicKey());
            char[] charArray = "password".toCharArray();
            Intrinsics.checkExpressionValueIsNotNull(charArray, "(this as java.lang.String).toCharArray()");
            char[] charArray2 = "keypass".toCharArray();
            Intrinsics.checkExpressionValueIsNotNull(charArray2, "(this as java.lang.String).toCharArray()");
            Intrinsics.checkExpressionValueIsNotNull(privKey, "privKey");
            KeyStore keyStore = save(storeFileName, charArray, "alias", charArray2, privKey, cert);
            char[] charArray3 = "password".toCharArray();
            Intrinsics.checkExpressionValueIsNotNull(charArray3, "(this as java.lang.String).toCharArray()");
            Intrinsics.checkExpressionValueIsNotNull(privKey, "privKey");
            CertKeyStore certKeyStore = new CertKeyStore(keyStore, charArray3, cert, privKey);
            return certKeyStore;
        } catch (Exception e) {
            System.out.printf("cacert store create error %s\n", e.toString());
            throw e;
        }
    }

    private final KeyStore save(String storeFileName, char[] storePass, String alias, char[] keyPass, PrivateKey privKey, X509Certificate cert) {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, storePass);
        keyStore.setKeyEntry(alias, privKey, keyPass, new Certificate[]{cert});
        FileOutputStream fout = new FileOutputStream(storeFileName);
        keyStore.store(fout, storePass);
        fout.close();
        Intrinsics.checkExpressionValueIsNotNull(keyStore, "keyStore");
        return keyStore;
    }

    private final X509Certificate generateV3Certificate(KeyPair pair) throws InvalidKeyException, NoSuchProviderException, SignatureException {
        X509v3CertificateBuilder builder = new X509v3CertificateBuilder(new X500Name("CN=Packet Capture CA Certificate"), BigInteger.valueOf(System.currentTimeMillis()), new Date(System.currentTimeMillis() - ONEYEAR_IN_MS), new Date(System.currentTimeMillis() + (ONEYEAR_IN_MS * 10)), Locale.ENGLISH, new X500Name("CN=Packet Capture CA Certificate"), SubjectPublicKeyInfo.getInstance(pair.getPublic().getEncoded()));
        builder.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));
        builder.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(164));
        builder.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth));
        builder.addExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName(1, "test@test.test")));
        ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(pair.getPrivate());
        X509Certificate certificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate(builder.build(signer));
        Intrinsics.checkExpressionValueIsNotNull(certificate, "JcaX509CertificateConver…te(builder.build(signer))");
        return certificate;
    }

    private final KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC);
        kpGen.initialize(1024, new SecureRandom());
        KeyPair generateKeyPair = kpGen.generateKeyPair();
        Intrinsics.checkExpressionValueIsNotNull(generateKeyPair, "kpGen.generateKeyPair()");
        return generateKeyPair;
    }
}