如何在没有用户交互的情况下以编程方式在 Android 上安装 CA 证书
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11657172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to install CA certificate programmatically on Android without user interaction
提问by Pedro
I'm trying to install certificates without prompting the user. I know this is not good practice, but that's what PM wants.
我正在尝试在不提示用户的情况下安装证书。我知道这不是一个好的做法,但这正是 PM 想要的。
Using KeyChain.createInstallIntent()
, I can get Android to launch the certificate installation dialog by calling startActivity
. However, when I pass the intent to sendBroadcast
, nothing happens. Maybe the platform doesn't support this for security reasons?
使用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) {
回答by Nikolay Elenkov
You can only install certificates silently if you have system privileges. Showing up a confirmation dialog is intentional, since trusting certificates can have serious consequences -- Android could happily open phishing sites without a warning, etc. That said, the dialog in ICS/JB is pretty bad -- it doesn't tell you what certificate you are installing and who issued it, just that it's a CA certificate, which is kind of obvious.
如果您具有系统权限,则只能静默安装证书。显示确认对话框是有意的,因为信任证书可能会产生严重后果——Android 可以在没有警告的情况下愉快地打开网络钓鱼站点,等等。也就是说,ICS/JB 中的对话框非常糟糕——它没有告诉你什么您正在安装的证书以及谁颁发的证书,只是它是一个 CA 证书,这很明显。
So, either use the public KeyChain
API and use startActivity()
to get the confirmation dialog, or pre-provision devices before handling them to users.
因此,要么使用公共KeyChain
API 并用于startActivity()
获取确认对话框,要么在将设备处理给用户之前预先配置设备。
Update: In Android 4.4, DevicePolicyManager
has a hidden API (installCaCert
) that allows you to install certificates silently. You need the MANAGE_CA_CERTIFICATES
permission, which is signature|system
, so still not doable for user-installed apps.
更新:在 Android 4.4 中,DevicePolicyManager
有一个隐藏的 API ( installCaCert
),允许您静默安装证书。您需要MANAGE_CA_CERTIFICATES
权限,即signature|system
,因此对于用户安装的应用程序仍然不可行。
回答by CommonsWare
Using KeyChain.createInstallIntent(), I can get Android to launch the certificate installation dialog by calling startActivity. However, when I pass the intent to sendBroadcast, nothing happens.
使用KeyChain.createInstallIntent(),我可以通过调用 startActivity 让 Android 启动证书安装对话框。但是,当我将意图传递给 sendBroadcast 时,没有任何反应。
Few if any Intent
objects that you would pass to startActivity()
would work with sendBroadcast()
. They are independent channels of the quasi-message bus that is the Intent
system.
Intent
您将传递给的任何对象都很少startActivity()
与sendBroadcast()
. 它们是作为Intent
系统的准消息总线的独立通道。
回答by Chris Noldus
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.
对于系统应用程序开发人员,我找到了以下解决方案,注意您必须使用系统用户 ID 运行应用程序并使用系统密钥对应用程序进行签名,否则服务将拒绝您安装证书的尝试。
Step 1- Create interface
第 1 步-创建界面
Create a new package in your project: android.security, then copy IKeyChainService.aidlinto this package.
在您的项目中创建一个新包:android.security,然后将IKeyChainService.aidl复制到该包中。
Step 2- Bind to service and install certificate
步骤 2-绑定到服务并安装证书
The Activity gives an example of how to install a CA certificate:
活动给出了如何安装 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();
}
}
I hope this helps someone - it took me a long time to work it out :)
我希望这对某人有所帮助-我花了很长时间才弄明白:)
回答by ospider
If you have root privilege, you could copy the certs file to /data/misc/user/0/cacerts-added/
如果您有 root 权限,您可以将 certs 文件复制到 /data/misc/user/0/cacerts-added/
回答by Konjengbam
Only a system user application can silently install a CA certificate. On Lollipop though, Google introduced silent certificate management API through DevicePolicyManager, but you would either have to be Android-for-Work profile owner or device owner.
只有系统用户应用程序可以静默安装 CA 证书。不过,在 Lollipop 上,Google 通过 DevicePolicyManager 引入了静默证书管理 API,但您必须是 Android-for-Work 配置文件所有者或设备所有者。
回答by Sebastián Rodriguez
Based on the @ospider's answer, i managed to succesfully install the cert like this way:
根据@ospider的回答,我设法像这样成功安装了证书:
adb shell mkdir -p /data/misc/user/0/cacerts-added
adb push certificate.cer /data/misc/user/0/cacerts-added/807e3b02.0
# Maybe these two lines are not strictly necessary...
adb shell chmod 644 /data/misc/user/0/cacerts-added/807e3b02.0
adb shell chown system:system /data/misc/user/0/cacerts-added/807e3b02.0
I got the name of the copied file (807e3b02.0
) by installing manually the cert i wanted to automate and seeing how Android saved it (whith adb shell ls -l /data/misc/user/0/cacerts-added/
)
我807e3b02.0
通过手动安装我想要自动化的证书并查看 Android 如何保存它来获得复制文件的名称( adb shell ls -l /data/misc/user/0/cacerts-added/
)
Hope this help.
希望这有帮助。
Regards.
问候。