2012-06-21 1 views
3

내가 개발하고있는 응용 프로그램의 경우 CA와 사용자 인증서 및 개인 키를 그 또는 그녀의 집중없이 설치할 수 있어야합니다.사용자 동의없이 ICS에 (x509/pk12) 인증서를 어떻게 설치합니까?

필자는 전체 시스템 권한을 보유하게되며,이 경우 사용자가 암호를 알아낼 것으로 추정됩니다. x509는 CA 인증서 또는 pk12의 경우 사용자 인증서 + 개인 키 파일이고, 암호는 USer 인증서 + 개인 키입니다. WPA-EAP WiFi 설정을 자동으로 설정하려면이 작업을 수행해야하며, 직원이 아무 것도 알아 차리지 않고도이 작업을 수행하기를 원합니다.

설치되어있는 모든 인증서를 나열하는 방법을 알고 있다면 매우 감사 할 것입니다.

나는 하루 종일 점검했고 keystore_cli으로 약간의 테스트를 마쳤으며, 더 현명하지 않으면 서 CertInstaller 코드를 읽었습니다. 거기에는 패키지 전체가 있으므로 직접 메소드를 호출 할 수는 없습니다. + com.android.settings ","com.android.settings.CredentialStorage "로 더 멀리 전송하는 것 같습니다.

모든 조언은 매우 좋을 것입니다. 그 궁금하십시오.


편집, 여기에 내가 CA 인증서와 함께 그것을 어떻게. 응용 프로그램은 시스템 사용자 (안드로이드 매니페스트 android:sharedUserId="android.uid.system")로 실행 할 수 있어야한다.

  // Android...why do you enjoy doing my life so difficult... 
      try { 
       Class<?> keyStoreClass = WifiConfiguration.class.getClassLoader().loadClass("android.security.KeyStore"); 

       Method getInstanceMethod = keyStoreClass.getMethod("getInstance"); 
       Object keyStore = getInstanceMethod.invoke(null); 

       Log.d("DeviceManager", "Got keystore" + keyStore.toString()); 

       // Put(Key, Value) 
       Method putCertificateMethod = keyStoreClass.getMethod("put", String.class, byte[].class); 

       Log.d("DeviceManager", "Putting..."); 

       RandomAccessFile file = new RandomAccessFile("/data/ca.crt", "r"); 
       byte[] b = new byte[(int)file.length()]; 
       file.read(b); 
       byte[] cacert = b; 

       Log.d("DeviceManager", "Certificate is bytes long: " + b.length); 

       putCertificateMethod.invoke(keyStore, "CACERT_name", cacert); 


      } catch (ClassNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } catch (InvocationTargetException e) { 
       e.printStackTrace(); 
      } catch (NoSuchMethodException e) { 
       e.printStackTrace(); 
      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

답변

1

다행히 재고 장치에서는이 기능을 사용할 수 없습니다. 그렇지 않으면 임의의 악성 앱이 사용자의 동의없이 CA 인증서를 설치할 수 있습니다. 소규모 장치 세트가있는 경우 미리 프로비저닝해야 할 수 있습니다. PKCS # 12 파일은 암호로 보호되어 누군가가 암호를 입력해야합니다.

'전체 시스템 권한'의 의미가 확실하지 않지만 플랫폼 코드로 앱을 연결하고 시스템 인증서로 서명 할 수있는 경우 KeyChainService 메소드를 직접 호출 할 수 있습니다. 그러면 인증서를 설치할 수 있습니다. 또한 CA 인증서는 파일로 저장되기 때문에 올바른 위치로 복사 할 수 있습니다. 여기에 몇 가지 세부 정보가 있습니다 : http://nelenkov.blogspot.jp/2011/11/ics-credential-storage-implementation.html

+0

안녕하세요, 귀하의 답변과 훌륭한 기사에 감사드립니다. 그들은 내가이 방식의 작동 방식에 관해 더 많이 배울 수 있도록 도와주었습니다. 우선. 전체 sysstem 권한을 말하는 것은 실제로 앱이 시스템 인증서로 서명된다는 것을 의미합니다. 이것은 자신의 하드웨어 및 소프트웨어를 생산하는 회사의 장치 관리 솔루션으로 안드로이드 에코 시스템을 완전히 제어 할 수 있습니다. KeyChainService를 검사 한 결과, 거기에'installCaCertificate (byte [] caCertificate)'메소드가 발견되었습니다. 그러나 별칭을 신경 쓰지 않고 인증서를 바이트로만 사용하는 것으로 보입니다. – Aldrian

+0

별칭도 할당 할 수 있어야합니다.이 설정은 Wi-Fi 구성을 사용자 장치에 자동으로 전송하는 데 사용되므로 알지 못하거나 신경 쓰지 않아도됩니다. 이제 Wifi 및 WPA-EAP의 경우 서버에서 CA 인증서 및/또는 개인 인증서 + 키를 요구할 수 있으므로 이러한 모든 것을 설치할 수 있어야합니다. CA 인증서의 경우,'/ data/misc/keychain/cacerts-added'와'/ data/misc/keystore /'에 설치 될 것입니다.나는 cacerts가 추가 된 폴더에 ca 인증서를 성공적으로 전송했으며 설치된 인증서에는 나타나지만 Wifi 목록에는 나타나지 않습니다. [cont ...] – Aldrian

+0

이것은/data/misc/keystore 폴더에 들어가기를 요구합니다. 1000CACERT_ca를 볼 수 있으며, WPA EAP리스트에도 나타날 것입니다. – Aldrian

0

다음 방법은 CA 인증서와 사용자 인증서로 WPA/EAP-TLS 무선 구성을 구성합니다. 다른 EAP 구성에도 사용할 수 있습니다.

 
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(); 
} 

관련 문제