Я искал это в течение нескольких недель и не могу найти ответ нигде. Я пытаюсь сделать следующее для Android. Этот код из приложения C#, которое я написал, но переносил его на Android. Конечная точка веб-сайта требует, чтобы сертификат был прикреплен к запросу о взаимной аутентификации для совершения вызова веб-службы.Сертификаты для Android и клиентов
string certThumbprint = "E1313F6A2D770783868755D016CE748F6A9B0028";
X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
certStore.Open(OpenFlags.ReadOnly);
}
catch (Exception e)
{
if (e is CryptographicException)
{
Console.WriteLine("Error: The store is unreadable.");
}
else if (e is SecurityException)
{
Console.WriteLine("Error: You don't have the required permission.");
}
else if (e is ArgumentException)
{
Console.WriteLine("Error: Invalid values in the store.");
}
else
{
throw;
}
}
X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, false);
certStore.Close();
if (0 == certCollection.Count)
{
throw new Exception("Error: No certificate found containing thumbprint " + certThumbprint);
}
X509Certificate2 certificate = certCollection[0];
return certificate;
Я тогда делал это (запрос является HttpWebRequest):
request.ClientCertificates.Add(cert);
Это отлично работает в C# однако когда я перехожу на Android я получаю «файл не найден» ошибка на getInputStream(). Вот мой Android код:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new FileInputStream("/sdcard/Certificate.pfx"));
KeyHelper kh = new KeyHelper();
Certificate ca = kh.GetKey("Password");
String keyStoreType = KeyStore.getDefaultType();
keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "Password".toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(),null,new SecureRandom());
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();
urlConnection.setRequestProperty("x-ms-version",AZURE_REST_VERSION);
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("GET");
urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.connect();
InputStream in = new BufferedInputStream(urlConnection.getInputStream()); //<-----Blows up here
} catch (KeyStoreException e) {
throw new KeyStoreException("Keystore Exception",e);
} catch (NoSuchAlgorithmException e) {
throw new NoSuchAlgorithmException("Algorithm exception",e);
} catch (KeyManagementException e) {
throw new KeyManagementException("Key Exception", e);
}
Я пытался поставить скрипач между эмулятором и конечной точкой, и он возвращается с 200. Я думаю, что это потому, что мой сертификат в моем местном частном магазине на моем Dev машине. Есть предположения?
Хотя heplful это не практическое решение, поскольку вам нужно добавить хранилище ключей к самому проекту андроида. Это побеждает цель, поскольку, хотя у меня уже есть сертификат, конечный пользователь может загрузить его в приложение, мне нужно создать хранилище ключей и заполнить его сертификатом. После реализации этого кода я теперь получаю ошибку SSLPeerUnverifiedError «no peer certificate». Самоподписанный сертификат существует как на стороне клиента, так и на стороне сервера. Таким образом, поиск продолжается. – AnthonyBCodes