如何在没有用户交互的情况下以编程方式安装CA证书

我正在尝试安装证书而不提示用户。 我知道这不是一个好的做法,但这是PM想要的。

使用KeyChain.createInstallIntent() ,我可以让Android通过调用startActivity启动证书安装对话框。 但是,当我传递意图sendBroadcast ,没有任何反应。 也许平台不支持这个安全的原因呢?

 String CERT_FILE = Environment.getExternalStorageDirectory() + "/test/IAT.crt"; Intent intent = KeyChain.createInstallIntent(); try { FileInputStream certIs = new FileInputStream(CERT_FILE); byte [] cert = new byte[(int)certFile.length()]; certIs.read(cert); X509Certificate x509 = X509Certificate.getInstance(cert); intent.putExtra(KeyChain.EXTRA_CERTIFICATE, x509.getEncoded()); intent.putExtra(KeyChain.EXTRA_NAME, "IAT Cert"); EapActivity.this.startActivityForResult(intent, 0); // this works but shows UI EapActivity.this.sendBroadcast(intent); // this doesn't install cert } catch (IOException e) { 

Solutions Collecting From Web of "如何在没有用户交互的情况下以编程方式安装CA证书"

如果您拥有系统权限,则只能以无提示方式安装证书。 显示一个确认对话框是故意的,因为信任证书可能会带来严重的后果 – Android可以高兴地打开钓鱼网站,而不会有任何警告等等。也就是说,ICS / JB中的对话非常糟糕 – 它不会告诉你什么您正在安装的证书以及是谁颁发的,只是它是一个CA证书,这是很明显的。

因此,使用公钥KeyChain API并使用startActivity()来获取确认对话框,或者在将设备处理给用户之前预先提供设备。

更新:在Android 4.4中, DevicePolicyManager具有一个隐藏的API( installCaCert ),允许您静默安装证书。 您需要具有signature|systemMANAGE_CA_CERTIFICATES权限,因此仍然无法用于用户安装的应用程序。

使用KeyChain.createInstallIntent() ,我可以让Android通过调用startActivity启动证书安装对话框。 但是,当我传递意图sendBroadcast,没有任何反应。

几乎没有任何可以传递给startActivity() Intent对象可以与sendBroadcast() 。 它们是Intent系统的准消息总线的独立通道。

对于非系统应用程序开发人员来说,简单的答案是没有用户交互就无法完成。

对于系统应用程序开发人员,我发现了以下解决scheme,注意您必须使用系统用户标识运行应用程序,并使用系统密钥对应用程序进行签名,否则服务将拒绝您尝试安装证书。

第1步创build界面

在你的项目中创build一个新的包: android.security ,然后将IKeyChainService.aidl复制到这个包中。

第2步绑定服务并安装证书

该活动给出了如何安装CA证书的示例:

 public class KeyChainTest extends Activity { private final Object mServiceLock = new Object(); private IKeyChainService mService; private boolean mIsBoundService =false; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { synchronized (mServiceLock) { mService = IKeyChainService.Stub.asInterface(service); mServiceLock.notifyAll(); try { byte[] result = YOUR_CA_CERT_AS_BYTE_ARRAY //The next line actually installs the certificate mService.installCaCertificate(result); } catch (Exception e) { //EXception handling goes here } } } @Override public void onServiceDisconnected(ComponentName name) { synchronized (mServiceLock) { mService = null; } } }; private void bindService() { mIsBoundService = bindService(new Intent(IKeyChainService.class.getName()), mServiceConnection, Context.BIND_AUTO_CREATE); } private void unbindServices() { if (mIsBoundService) { unbindService(mServiceConnection); mIsBoundService = false; } } @Override public void onDestroy () { unbindServices(); } @Override protected void onStart() { super.onStart(); // Bind to KeyChainService bindService(); } } 

我希望这可以帮助一个人 – 我花了很长时间来解决这个问题:)

只有系统用户应用程序可以静默安装CA证书。 不过,在棒棒糖上,Google通过DevicePolicyManager引入了无声的证书pipe理API,但是您必须是Android-for-Work个人资料所有者或设备所有者。

如果您具有root权限,则可以将certs文件复制到/data/misc/user/0/cacerts-added/