如何使用Volley使用SSL证书获取SSLSocketFactory

时间:2014-12-02 11:04:54

标签: android ssl android-volley

我正在尝试使用Volley将图像上传到服务器。我准备获取SSLSocketFactory的方法,并在其方法中使用SSL证书获取SSLSocketFactory。我用不同的方法从这个SSLSocketFactory实例获取RequestQueue。

但是,错误“inStream为空”的CertificateException错误发生在//错误显示的位置。

原因似乎是R.raw.sslcrt的内容。 R.raw.sslcrt的内容如下。

—–BEGIN CERTIFICATE—–
MIID1TCCAr2gAwIBAgID
// omission
0wVaydWTQBUbHq3tw==
—–END CERTIFICATE—–
—–BEGIN CERTIFICATE—–
MIIDfTCCAuagAwIBAgID
// omission
84dJzjA1BOoa+Y7mHyhD
—–END CERTIFICATE—–

我不知道R.raw.sslcrt的内容应该是任何内容。 CRT文件或CSR文件或其他?目前我已经使用了服务器的CRT文件而没有编辑。

我该怎么办?

private static SSLSocketFactory
getSSLSocketFactory(Context context)
        throws CertificateException,
        NoSuchAlgorithmException,
        KeyStoreException,
        KeyManagementException,
        IOException{

    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    InputStream inputStream = context.getResources().openRawResource(R.raw.sslcrt);

    // Error
    Certificate certificate = certificateFactory.generateCertificate(inputStream);

    String keyType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", certificate);
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
            TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
    return sslContext.getSocketFactory();
}

1 个答案:

答案 0 :(得分:0)

请记住: PEM是Base64编码的DER证书

我认为这里的问题可能是您希望使用PEM格式的证书提供generateCertificate方法(我认为它只接受DER,但我无法在docementation中找到它)。尝试将其转换为DER(您可以在代码中或使用openssl)。您甚至可以在应用程序中将整个证书存储为String。

只要你有PEM字符串就可以试试这个:

public X509Certificate parseCertificate(String certificate) throws CertificateException {
    byte[] decoded = Base64.decode(certificate.replaceAll("-----BEGIN CERTIFICATE-----", "").replaceAll("-----END CERTIFICATE-----", ""));
    return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(decoded));
}

解决问题的另一个选择是使用openssl和BouncyCastle库创建BKS密钥库,向其添加证书并存储在原始文件夹中。

您也可以尝试使用BouncyCastle PemParser:http://www.bouncycastle.org/docs/pkixdocs1.5on/org/bouncycastle/openssl/PEMParser.html