java - 将 PFX 静默安装到 Android 系统受信任的 CA 用户 keystore 中

标签 java android ssl-certificate x509 pfx

我的公司正在开发一个使用 Android 平板电脑的信息亭。我们使用 TLS 与私有(private)服务器通信。我们拥有平台 key 来授予我们的客户端应用程序系统权限。仅当客户端使用授权的客户端证书进行连接时,服务器才会允许客户端进行连接。为了制造平板电脑,我们需要将 PFX 格式的客户端证书和私钥加载到 Android 系统可信 CA 用户 keystore 中。多个应用程序需要从用户 keystore 检索私钥和证书链。我们的制造过程是一个自动化过程,没有人可以单击"is"和“确定”来屏幕提示。我们还需要静默证书安装过程来替换将来过期的客户端证书。

如何将 PFX 文件从平台签名应用程序静默加载到系统受信任的 CA 用户存储中,无需用户交互?

最佳答案

这仅适用于企业 WiFi 配置。以下方法将使用 CA 证书和用户证书配置 WPA/EAP-TLS wifi 配置。

public static void createEapConfig(Context context, String ssid, String password, boolean connectAutomatically, boolean hiddenNetwork,
                                   Integer eapMethod, Integer phase2, String identity, String anonymousIdentity, String caCertificateData,
                                   String clientCertificateData, String clientCertPass) {
    if (ssid == null || eapMethod == null) {
        return;
    }
    WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    boolean connect = connectAutomatically;
    boolean isWifiReceiverRegistered = false;
    try {
        Logger.logEnteringOld();

        WifiConfiguration config = new WifiConfiguration();
        config.SSID = "\"" + ssid + "\"";
        config.hiddenSSID = hiddenNetwork;//false; //hidden network is always set to false.
        config.status = WifiConfiguration.Status.ENABLED;
        config.priority = 40;
        try {
            wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class).invoke(wifiManager, config, false);
        } catch (Exception e) {
            Logger.logError(e);
        }
        Settings.isWifiHotspotEnabled(false);
        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
            Thread.sleep(5000);
        }

        if (connect) {
            lastActNetId = wifiManager.getConnectionInfo().getNetworkId();
            wifiManager.disableNetwork(lastActNetId);
            wifiManager.disconnect();
        }
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);

        // Set defaults
        if (phase2 == null) phase2 = WifiEnterpriseConfig.Phase2.NONE;
        if (identity == null) identity = "";
        if (anonymousIdentity == null) anonymousIdentity = "";
        if (caCertificateData == null) caCertificateData = "";
        if (clientCertificateData == null) clientCertificateData = "";
        if (Build.VERSION.SDK_INT >= 18) {
            if (Util.isNullOrEmpty(password)) {
                config.enterpriseConfig.setPassword(password);
            }

            config.enterpriseConfig.setEapMethod(eapMethod);

            if (phase2 != null) {
                config.enterpriseConfig.setPhase2Method(phase2);
            }
            if (!Util.isNullOrEmpty(identity)) {
                config.enterpriseConfig.setIdentity(identity);
            }
            if (!Util.isNullOrEmpty(anonymousIdentity)) {
                config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity);
            }
            InputStream is = null;
            if (!Util.isNullOrEmpty(caCertificateData)) {
                try {
                    byte[] decodedCaCert = Base64.decode(caCertificateData);
                    //is = new FileInputStream(Environment.getExternalStorageDirectory()+"/local-root(1).cer" );
                    CertificateFactory cf = CertificateFactory.getInstance("X.509");
                    try {

                        is = new ByteArrayInputStream(decodedCaCert);
                        X509Certificate caCert = (X509Certificate) cf.generateCertificate(is);
                        config.enterpriseConfig.setCaCertificate(caCert);
                    } catch (CertificateException ex) {
                        Logger.logError(ex);
                    } finally {
                        if (is != null) {
                            is.close();
                        }
                    }
                } catch (Throwable t) {
                    Logger.logError(t);
                }
            }
            if (!Util.isNullOrEmpty(clientCertificateData) && !Util.isNullOrEmpty(clientCertPass)) {
                try {
                    byte[] decodedClientCert = Base64.decode(clientCertificateData);
                    KeyStore p12 = KeyStore.getInstance("pkcs12");
                    is = new ByteArrayInputStream(decodedClientCert);
                    //is = new FileInputStream(Environment.getExternalStorageDirectory()+"/createdDERCert(1).pfx");
                    p12.load(is, clientCertPass.toCharArray());
                    Enumeration aliases = p12.aliases();
                    for (String alias : Collections.list(aliases)) {

                        if (alias == null) {
                            continue;
                        }

                        PrivateKey privateKey = (PrivateKey) p12.getKey(alias, clientCertPass.toCharArray());
                        if (privateKey == null) {
                            continue;
                        }

                        X509Certificate clientCert = (X509Certificate) p12.getCertificate(alias);

                        if (clientCert != null) {
                            config.enterpriseConfig.setClientKeyEntry(privateKey, clientCert);
                        }
                    }
                } catch (Throwable t) {
                    Logger.logError(t);
                } finally {
                    if (is != null) {
                        try {
                            is.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        int networkId = -1;
        networkId = wifiManager.addNetwork(config);

        wifiManager.enableNetwork(networkId, true);
        wifiManager.saveConfiguration();

        if (connect) {
            wifiManager.reconnect();
            IntentFilter filter = new IntentFilter();
            filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
            Settings.cntxt.registerReceiver(wifiReceiver, filter);
            isWifiReceiverRegistered = true;
            Thread.sleep(15000);
        }
    } catch (InterruptedException ie) {
        if (NetworkStateReceiver.activeConnection(Settings.cntxt)) {
            lastActNetId = wifiManager.getConnectionInfo().getNetworkId();
        }
    } catch (Exception ex) {
        Logger.logError(ex);
    } finally {
        // unregister wifi state receiver
        if (connect && isWifiReceiverRegistered) {
            isWifiReceiverRegistered = false;
            Settings.cntxt.unregisterReceiver(wifiReceiver);
        }
    }

    Logger.logEnteringOld();
}

关于java - 将 PFX 静默安装到 Android 系统受信任的 CA 用户 keystore 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44860422/

相关文章:

java - 未调用 Android WebView evaluateJavaScript 回调

android - MediaPlayer错误(1,-1010)MEDIA_ERROR_UNKNOWN/MEDIA_ERROR_MALFORMED

ssl - ChromeDriver 仅打开具有有效 SSL 证书的网站

java - 没有 keystore 的 key 工具

java - 查找句子中所有元音的出现情况

java - 如何在 Java EE Web 应用程序中使用延迟实体加载?

java - 如何在Java 8中使用声音效果?蛇吃苹果

Java 程序读取用户输入直到输入 0,同时还会进行一些计算(偶数/奇数、平均值等)

java - LibGDX 不使用 Android Assets 文件夹

c++ - SSL 证书验证失败 : Using OpenSSL