how to install CA certificate programmatically on Android without user interaction

后端 未结 7 1707
别跟我提以往
别跟我提以往 2020-12-02 11:04

I\'m trying to install certificates without prompting the user. I know this is not good practice, but that\'s what PM wants.

Using KeyChain.createInstallIntent(), I

7条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-02 11:20

    For non-system app developers - the simple answer is it can not be done without user interaction.

    For System App developers, I found the following solution, NB you must run the app with the system user id and sign the app with the system key or the service will reject your attempts to install the certificate.

    Step 1 - Create interface

    Create a new package in your project: android.security, then copy IKeyChainService.aidl into this package.

    Step 2 - Bind to service and install certificate

    The Activity gives an example of how to install a CA certificate:

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

    I hope this helps someone - it took me a long time to work it out :)

提交回复
热议问题