我有一个适用于 Android 手机的 MDM 应用程序。我需要从下载文件夹中获取证书并将其安装在 Android 上。
我写了一个函数来安装它(如果这是错误的,请纠正我)。现在我如何获得此证书(我需要它才能使用它并从另一个应用程序访问它)? 我在文档中找不到任何有关如何使用它的示例,也没有文章。我写了一个函数,但它找不到私钥。
证书的扩展名为“.pfx”(PKCS12)。该证书由证书颁发机构创建。用户在安装证书时会输入密码。
请注意,这是客户端证书,我需要密码才能使用它
我尝试通过意图安装它。它因错误而崩溃。我需要 MDM 才能安装并选择证书本身
override fun installCertificate(certificate: File, password: String) {
Log.i(TAG, "[installCertificate] Start install certificate certificate: $certificate | password: $password")
val keyStore = KeyStore.getInstance(KEY_STORE_TYPE)
FileInputStream(certificate).use { fis -> keyStore.load(fis, password.toCharArray()) }
val alias = keyStore.aliases().nextElement()
val key = keyStore.getKey(alias, password.toCharArray()) as PrivateKey
val certChain = keyStore.getCertificateChain(alias)
val dpm = activity.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val adminComponentName = LegacyUtils.getAdminComponentName(activity)
val certData = secretEncryptor.getCertificate(keyStore) as? X509Certificate ?: throw Exception()
val certificateAlias = certData.subjectX500Principal.name
val isOverwrite = dpm.installKeyPair(adminComponentName, key, certChain, alias, 0)
lastAlias = alias
Log.i(TAG,
"[installCertificate] Certificate $certificate installed | alias: $lastAlias | isOverwrite: $isOverwrite")
}
private fun getCertificate(alias: String) {
KeyChain.getPrivateKey(activity, alias)?.let { privateKey ->
KeyChain.getCertificateChain(activity, alias)?.let { certChain ->
val certificate = certChain.firstOrNull()
if (certificate != null) {
Log.i(TAG, "[getCertificate] Сертификат найден | alias: $alias")
// TODO: work with certificate
} else {
Log.e(TAG, "[getCertificate] Certificate not found | alias: $alias")
}
} ?: run {
Log.e(TAG, "[getCertificate] No certificate chain found | alias: $alias")
}
} ?: run {
Log.e(TAG, "[getCertificate] Private key not found | alias: $alias")
}
}
CoroutineScope(Dispatchers.IO).launch {
getCertificate(lastAlias)
}
[checkCertificatesAndInstallIfExist] certificates: [/storage/emulated/0/Download/cert.pfx]
2024-08-06 11:08:25.473 15588-15588 CertificatesManagerImp com.hmdm.launcher I [installCertificate] Start install certificate certificate: /storage/emulated/0/Download/cert.pfx | password: 1234
2024-08-06 11:08:26.375 15588-15588 CertificatesManagerImp com.hmdm.launcher I [installCertificate] Certificate /storage/emulated/0/Download/cert.pfx installed | alias: tq-70b931d7-cb80-4e2e-a617-c4d59435b8f4 | isOverwrite: true
2024-08-06 11:08:27.498 15588-15659 CertificatesManagerImp com.hmdm.launcher E [getCertificate] Private key not found | alias: tq-70b931d7-cb80-4e2e-a617-c4d59435b8f4
我也尝试通过
KeyStore
获得证书。所有调用都返回 null 并在 LogCat 中出现异常
private fun getCertificate(alias: String) {
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
val key1 = keyStore.getKey(alias, null)
val key2 = keyStore.getKey(alias, "1234".toCharArray())
val certificate1 = keyStore.getCertificateChain(alias)
val certificate2 = keyStore.getCertificate(alias)
val certificate3 = keyStore.getEntry(alias, null) as? KeyStore.PrivateKeyEntry
Log.i(TAG, "[getCertificate] Certificate $certificate3 | alias: $alias ")
}
2024-08-06 18:01:03.781 6289-6878 KeyStore com.hmdm.launcher W KeyStore exception
android.os.ServiceSpecificException: (code 7)
at android.os.Parcel.createException(Parcel.java:2085)
at android.os.Parcel.readException(Parcel.java:2039)
at android.os.Parcel.readException(Parcel.java:1987)
at android.security.keystore.IKeystoreService$Stub$Proxy.get(IKeystoreService.java:978)
at android.security.KeyStore.get(KeyStore.java:236)
at android.security.KeyStore.get(KeyStore.java:225)
at android.security.keystore.AndroidKeyStoreSpi.engineGetCertificate(AndroidKeyStoreSpi.java:165)
at java.security.KeyStore.getCertificate(KeyStore.java:1120)
at com.hmdm.launcher.certificates.CertificatesManagerImp.getCertificate(CertificatesManagerImp.kt:109)
at com.hmdm.launcher.certificates.CertificatesManagerImp.access$getCertificate(CertificatesManagerImp.kt:29)
at com.hmdm.launcher.certificates.CertificatesManagerImp$getAllCertificates$1.invokeSuspend(CertificatesManagerImp.kt:98)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
您是否尝试过解绑 pfx 并单独安装它们?