25

ユーザーにプロンプ​​トを表示せずに証明書をインストールしようとしています。これが良い慣行ではないことはわかっていますが、それが首相の望みです。

を使用して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) {
4

7 に答える 7

14

システム権限がある場合にのみ、証明書をサイレントにインストールできます。証明書を信頼すると深刻な結果を招く可能性があるため、確認ダイアログを表示することは意図的なものです。Androidは警告なしにフィッシングサイトを喜んで開く可能性があります。とはいえ、ICS/JBのダイアログはかなり悪いです。インストールしている証明書とそれを発行した人、それがCA証明書であるということは、明らかです。

そのため、パブリックKeyChainAPIを使用startActivity()して確認ダイアログを取得するか、デバイスをユーザーに処理する前に事前にプロビジョニングします。

更新:Android 4.4には、証明書をサイレントにインストールできるDevicePolicyManager非表示のAPI( )があります。権限installCaCertが必要です。これは、ユーザーがインストールしたアプリではまだ実行できません。MANAGE_CA_CERTIFICATESsignature|system

于 2012-07-26T03:11:45.190 に答える
9

KeyChain.createInstallIntent()を使用すると、startActivity を呼び出して Android に証明書のインストール ダイアログを起動させることができます。しかし、sendBroadcast にインテントを渡しても何も起こりません。

Intentあなたが渡すオブジェクトがあれば、ほとんど動作しませstartActivity()sendBroadcast()。これらは、システムである準メッセージ バスの独立したチャネルですIntent

于 2012-07-25T20:01:45.967 に答える
7

非システム アプリ開発者の場合、簡単な答えは、ユーザーの操作なしでは実行できないということです。

システム アプリの開発者向けに、次の解決策を見つけました。注: システム ユーザー ID を使用してアプリを実行し、システム キーを使用してアプリに署名する必要があります。そうしないと、証明書のインストールの試みがサービスによって拒否されます。

ステップ 1 -インターフェースを作成する

プロジェクトに新しいパッケージ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();
    }
}

これが誰かの役に立てば幸いです-解決するのに長い時間がかかりました:)

于 2013-07-08T02:16:54.913 に答える