
"Плагин" для Android Java, позволяющий спрашивать пользователя о SSL-сертификатах.
MemorizingTrustManager (MTM) — это проект, позволяющий сделать использование SSL на Android более безопасным и осмысленным. При обнаружении неизвестного SSL-сертификата он спрашивает пользователя, принять ли сертификат однократно, постоянно или прервать соединение. Это шаг к предотвращению атак вида «человек посередине», которые возможны при слепом принятии любых недействительных, самоподписанных и/или просроченных сертификатов.
MTM нацелен на бесшовную интеграцию в ваше Android-приложение, а исходный код доступен под лицензией MIT.

MemorizingTrustManager используется в продакшене в yaxim XMPP-клиенте. Он пригоден к использованию и легко интегрируется, хотя пока не поддерживает проверку имени хоста (Java API делает её интеграцию сложной).
MTM легко интегрировать в ваше собственное приложение. Выполните следующие шаги или посмотрите демонстрационное приложение в каталоге example.
Скачайте исходный код MTM с GitHub или добавьте его как git-подмодуль:
# plain download:
git clone https://github.com/ge0rg/MemorizingTrustManager
# submodule:
git submodule add https://github.com/ge0rg/MemorizingTrustManager
Затем добавьте зависимость от библиотечного проекта в default.properties:
android.library.reference.1=MemorizingTrustManager
Отредактируйте ваш AndroidManifest.xml и добавьте элемент activity MTM непосредственно перед закрывающим тегом </application>.
...
<activity android:name="de.duenndns.ssl.MemorizingActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
/>
</application>
</manifest>
Подключение MemorizingTrustManager в HTTPS-соединениях:
// register MemorizingTrustManager for HTTPS
SSLContext sc = SSLContext.getInstance("TLS");
MemorizingTrustManager mtm = new MemorizingTrustManager(this);
sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(
mtm.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()));
Для SSLSocket следует сделать следующее:
// register MemorizingTrustManager for all SSLSockets
SSLContext sc = SSLContext.getInstance("TLS");
MemorizingTrustManager mtm = new MemorizingTrustManager(this);
HostnameVerifier hv = mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier());
sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
SSLContext.setDefault(sc);
// connect a socket
SSLSocket s = ...;
s.startHandshake();
if (!hv.verify(your_domain_name, sslSocket.getSession())) {
throw new CertificateException("Server failed to authenticate as " + your_domain_name);
}
Или, для Smack, вы можете использовать setCustomSSLContext():
org.jivesoftware.smack.ConnectionConfiguration connectionConfiguration = …
SSLContext sc = SSLContext.getInstance("TLS");
MemorizingTrustManager mtm = new MemorizingTrustManager(this);
sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
connectionConfiguration.setCustomSSLContext(sc);
connectionConfiguration.setHostnameVerifier(
mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier()));
По умолчанию MTM обращается к системному TrustManager, прежде чем спросить пользователя. Если вы не доверяете стандартному поведению, вы можете принудительно вызывать диалог при каждом новом соединении, передав конструктору параметр defaultTrustManager = null:
MemorizingTrustManager mtm = new MemorizingTrustManager(this, null);
Если вы хотите использовать другой нижележащий TrustManager, например AndroidPinning, просто передайте его в конструктор MTM:
X509TrustManager pinning = new PinningTrustManager(SystemKeyStore.getInstance(),
new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"}, 0);
MemorizingTrustManager mtm = new MemorizingTrustManager(this, pinning);
MTM использует java.util.logging (JUL) для ведения журнала. Если вы не настроили Handler для JUL, Android по умолчанию будет записывать все сообщения уровня Level.INFO и выше. Чтобы также получать отладочные сообщения (уровня Level.FINE и ниже), необходимо соответствующим образом настроить Handler. Пример проекта MTM содержит de.duenndns.mtmexample.JULHandler, который позволяет включать и отключать отладочное журналирование во время выполнения.
MemorizingTrustManager — не единственное подобное решение.
NetCipher — это Android-библиотека, созданная Guardian Project для повышения сетевой безопасности мобильных приложений. Она включает StrongTrustManager для более тщательной проверки сертификатов, независимое хранилище корневых CA-сертификатов и код для простой маршрутизации вашего трафика через сеть Tor с помощью Orbot.
AndroidPinning — ещё одна Android-библиотека, написанная Moxie Marlinspike, которая позволяет закреплять (pinning) сертификаты сервера, повышая защиту от MitM-атак масштаба государства. Используйте её, если ваше приложение предназначено для общения с конкретным сервером!
Пожалуйста, помогите перевести MTM на другие языки!