Вы можете включить сертификат X509 в комплект кода в качестве ресурса и поместить его в хранилище ключей.Но пользователю придется вручную зайти в хранилище сертификатов и доверять ему.Если пользователь ранее не использовал хранилище сертификатов, это приведет к нежелательному побочному эффекту, заставив его выбрать пароль в этой точке.
Следующий код будет считывать сертификат из файла ресурсов в формате PEM, но с----- BEGIN / END CERTIFICATE ----- строки удалены.Я использовал все элементы этого кода, но не в этой точной конфигурации.Если возникнут какие-либо проблемы, я с радостью постараюсь их решить.
Сертификат не будет доверенным, поэтому пользователю придется вручную войти в приложение хранилища сертификатов в разделе «Параметры устройства» и «Доверие»." сертификат.Убедитесь, что они понимают, что не могут отозвать сертификат.Эта операция не может быть отменена на устройстве без очистки и переустановки ОС.Единственный другой вариант - переиздать новый сертификат.
Если кто-то знает, как обойти эти финиширующие биты, дайте мне знать, и я включу решение в этот код или ссылку на то место, где оно существует сейчас.
X509Certificate _x509;
try {
// Get an input stream for the certificate in a resource file
InputStream rs = getClass().getResourceAsStream("/certificate.pem");
// PEM format is Base64 encoded
Base64InputStream b64is = new Base64InputStream(rs);
// Create the X509 certificate
_x509 = new X509Certificate(b64is);
// Clean up.
b64is.close();
rs.close();
// if the certificate is self signed this will perform a
// verfication check. For non-self signed certificates
// one could provide the signer's certificate in another
// resource file and validate it with that public key. Other
// versions of verify will verify it with a certificate in
// a keystore, but then we wouldn't need to do all this.
_x509.verify(_x509.getPublicKey());
System.out.println(_x509.getSubjectFriendlyName());
System.out.println(Integer.toHexString(_x509.hashCode()));
// Add the certificate to the DeviceKeyStore
KeyStore ks = DeviceKeyStore.getInstance();
// Associated data is set to null, but can be used if there is associated
// data known. You can use _x509.getStatus() instead of encoding the GOOD
// constant, but if the device can not find a revokation or validation list
// it will set the status to UNKNOWN which will confuse users. ks.getTicket()
// will prompt the user for permission for the program to access the key store.
// This may also cause the system to ask the user to set a password, unfortunately
// I can't remember, but I don't think it will if there is no private key in the
// certificate.
ks.set(null, _x509.getSubjectFriendlyName(), _x509, CertificateStatus.GOOD,
ks.getTicket() );
} catch (CertificateException ce) {
System.out.println(ce.toString());
} catch (CryptoException crypt) {
System.out.println(crypt);
} catch (IOException ioe) {
System.out.println(ioe.toString());
}