android - 从 Android 中的文件加载 SSL 证书

标签 android ssl

我正在尝试从文件加载自签名 SSL 证书。

据此 https://developer.android.com/reference/java/security/cert/CertificateFactory 它应该像这样工作:

private void LoadCert()
{
    try
    {
        AssetFileDescriptor assetFileDescriptor = this.getAssets().openFd("certbase64.cer");
        FileDescriptor fileDescriptor = assetFileDescriptor.getFileDescriptor();

        FileInputStream fis = new FileInputStream(fileDescriptor);
        BufferedInputStream bis = new BufferedInputStream(fis);

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        while (bis.available() > 0)
        {
            Certificate cert = cf.generateCertificate(bis);
            System.out.println(cert.toString());
        }
    }
    catch (Exception ex)
    {
        Log.d("Error", ex.getMessage());
    }
}

但是我收到此错误:

D/Error: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0c0000be:ASN.1 encoding routines:OPENSSL_internal:WRONG_TAG

文件:

-----BEGIN CERTIFICATE-----
MIICzjCCAbagAwIBAgIQRYyJrMpTfrlNFpAM8oS1VDANBgkqhkiG9w0BAQsFADAQ
MQ4wDAYDVQQDEwVTZWZmYTAeFw0xOTA2MjUyMDM5MTdaFw0yMDA2MjUwMDAwMDBa
MBAxDjAMBgNVBAMTBVNlZmZhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA+WFZChTqIIqamM0v+EeaZGhxopmkbmbCfL73dhBKZOOPq2ALwGWO9+ABjVDZ
Z5igcmhuYa29BymB9oMeyOWiyD1p/Wo1RUENCf5zTxOXdCCSF/up/ahj3q3M4afV
RNg8/4ld3r3m2u6XbOr2+y3p//9zgmilS5uswefM+p058uxBX4eoeDj7JhCNUuy5
xqWmvJAdaPL3/W/CjDva8c0HQ8GenMmi/JYwtjuZTYcKCk2Oxha5aCn0zu0DiwaY
s5/+x0/iyhg9kMXKjEDDTwu41wL1G90uKN7H+81uf+eEf0qHjwb+SMzugDiWbwcX
NZw4cL2fbi9z3QEy2k9Yov6NGQIDAQABoyQwIjALBgNVHQ8EBAMCBDAwEwYDVR0l
BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBABX/uVlO1dtFXj/bRDEz
S+gAc+5Bl4GggzRA5sxR1+FqS37AxkiHhsBweuxK5bx0wZBykzHhjmq24vnBRmt1
ucfffpJ2rJjlsoya6GEL/qTvj3gxvAH023M+V/Sdvg8K+reX/NGrRsVb19McDjbw
JqGyIDO4f5uOzMmky5zRoo8SbYTFZwPnRTL4oI99C7YWMGWOGPF/HvjqC2D+xRUy
cb8RWtj1ms6uwu96CQgU4i26a7xwVDP4mUAnOc7gdpdtQoDHROvz2LO04unEtfRd
jWO79/7nICA0miHo6QBVVxq5s6JOIyd1J5a2d8p+HZN4fDcEV6vB9VUU67WvjYXy
EIU=
-----END CERTIFICATE-----

知道问题出在哪里吗?

最佳答案

不确定这是否对您有帮助,但仍然有帮助。

sifrbl.SifrBlCert 只是文件所在的完整路径,

class TLSSocketFactory extends SSLSocketFactory {

private SSLSocketFactory internalSSLSocketFactory;

public TLSSocketFactory(SifrBl sifrbl) throws Exception  {

    FileInputStream fisTLS = new FileInputStream(sifrbl.SifrBlTls);
    FileInputStream fis = new FileInputStream(sifrbl.SifrBlCert);

    CertificateFactory cf = CertificateFactory.getInstance("X.509");

    Certificate ca;
    try {
        ca = cf.generateCertificate(fisTLS);
    } finally {
        fisTLS.close();
    }

    //Create a KeyStore containing our trusted CAs
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);

    KeyStore privatekeyStore = KeyStore.getInstance("PKCS12"); //
    privatekeyStore.load(fis, sifrbl.SifrBlPass.toCharArray());
    Log.i("jm_","KeyStore size: " + keyStore.size());

    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);
    Log.i("jm_","TrustManagerFactory size: " + tmf.getTrustManagers().length);

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); //x509
    kmf.init(privatekeyStore, sifrbl.SifrBlPass.toCharArray());
    Log.i("jm_","KeyManagerFactory size: " + kmf.getKeyManagers().length);


    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");//TLSv1.2
    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

    internalSSLSocketFactory = sslContext.getSocketFactory();

}

@Override
public String[] getDefaultCipherSuites() {
    return internalSSLSocketFactory.getDefaultCipherSuites();
}

@Override
public String[] getSupportedCipherSuites() {
    return internalSSLSocketFactory.getSupportedCipherSuites();
}

@Override
public Socket createSocket() throws IOException {
    return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}

@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}

@Override
public Socket createSocket(String host, int port) throws IOException {
    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}

@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}

@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}

@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}

private Socket enableTLSOnSocket(Socket socket) {
    if(socket != null && (socket instanceof SSLSocket)) {
        ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
    }
    return socket;
}

}

我这样调用它

TLSSocketFactory socketFactory = new TLSSocketFactory(sifrbl);
HttpsURLConnection urlConnection = null;
urlConnection.setSSLSocketFactory(socketFactory);

关于android - 从 Android 中的文件加载 SSL 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56927015/

相关文章:

android - 如何让移动设备显示图像而不是视频?

java - 如何在 Android MediaController 中实现快进/快退按钮的事件监听器

android - 将图像添加到自定义选项卡

java - Android 从设备设置安装自签名证书 SSL VS 以编程方式安装

ssl - 如何指定在我的 axis2 https 发件人上使用哪些密码?

python - Django 客户端证书提示

python - 在python请求中,SSLError : [SSL] PEM lib (_ssl. c :2600) mean?是什么意思

java - 当我完全删除该值时 onTextChanged

安卓软件开发生命周期

javascript - SSL UNABLE_TO_VERIFY_LEAF_SIGNATURE 的 Node.js 错误