使用.cer而不是.p12对android上的服务器进行身份验证

时间:2014-08-08 10:36:07

标签: android ssl certificate keystore pkcs#12

对于我当前的项目,我们在服务器上使用证书身份验证。直到现在我们使用PKCS12来实现它并且它工作正常。因为我们现在集成了PKCS11安全卡,所以我只能将证书作为标准.cer获得。到目前为止,我可以创建一个密钥库和SSLcontext,但由于某种原因服务器没有认识到我试图使用证书,如果我使用.cer。也许你们可以找到理由。

工作代码:

SSLContext ctx = SSLContext.getInstance("TLS");
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(new File("/data/local/tmp/admin.p12")), certpw.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore, certpw.toCharArray());
ctx.init(keyManagerFactory.getKeyManagers(),
                    new TrustManager[] { new X509TrustManager() {
                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[] {};
                        }

                        @Override
                        public void checkClientTrusted(
                                final X509Certificate[] arg0,
                                final String arg1)
                                throws CertificateException {

                        }

                        @Override
                        public void checkServerTrusted(
                                final X509Certificate[] arg0,
                                final String arg1)
                                throws CertificateException {

                        }
                    } }, new SecureRandom());

这里是带有.cer的无效代码:

SSLContext ctx = SSLContext.getInstance("TLS");
InputStream is = new FileInputStream("/data/local/tmp/admin.cer");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate caCert = (Certificate)cf.generateCertificate(is);

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, certpw.toCharArray());
ks.setCertificateEntry("caCert", caCert);

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(ks, certpw.toCharArray());

ctx.init(keyManagerFactory.getKeyManagers(),
                    new TrustManager[] { new X509TrustManager() {

                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[] {};
                        }

                        @Override
                        public void checkClientTrusted(
                                final X509Certificate[] arg0,
                                final String arg1)
                                throws CertificateException {

                        }

                        @Override
                        public void checkServerTrusted(
                                final X509Certificate[] arg0,
                                final String arg1)
                                throws CertificateException {

                        }
                    } }, new SecureRandom());

基本上唯一改变的是我现在创建一个空的密钥库并手动添加证书。

编辑: 我使用卡制造商提供的.so lib通过JNI获取.cer。它包含PKCS#11 API的实现。我可以从卡中获取私钥和​​公钥以及证书,但不知道我将如何使用它们来制作KeysStore。

1 个答案:

答案 0 :(得分:3)

您需要私钥。使用.p12文件,您可以使用它来建立与服务器的SSL连接。

当你从.p12转移到智能卡时,你做了很大的改变。我不知道是否可以通过PKCS#11接口使KeyStore与智能卡一起工作,或者如果Android上甚至可以使用PKCS#11接口(我不是Android开发人员)。

如果可以的话,尝试做一些研究。 您应该问自己(或谷歌)的问题:

  • Android上有PKCS#11界面吗?
  • 您的供应商是否为Android提供了PKCS#11库?
  • KeyStore可以使用PKCS#11库吗?