Предположим, Вы хотите безопасно передать некоторую конфиденциальную информацию из Вашего мобильного приложения на сервер.
SSL сертификат должен в этом помочь, не так ли? Все верно, но это только начало истории.
Нам очень часто приходится пересылать важные личные данные между мобильными приложениями в наших смартфонах и серверами, на которых находятся всевозможные сервисы, которыми мы пользуемся через смартфон. Возьмем для примера приложения мобильного банкинга. Естественно, никому бы не хотелось, чтобы какой-то хакер получил доступ к информации о банковском счете и, тем более, к деньгам его владельца. Безопасность имеет решающее значение для
онлайн банкинга, поэтому действительно необходимо использовать SSL сертификат для приложений мобильного банкинга. Но здесь есть один момент, который следует иметь в виду.
Что такое SSL pinning?
По умолчанию, устанавливая SSL соединение по протоколу HTTPS, клиент проверяет сертификат сервера по двум пунктам:
- что цепочку SSL сертификата можно проследить от Вашего личного SSL сертификата через промежуточные и до корневого сертификата доверенного центра сертификации.
- что Ваш SSL сертификат соответствует запрошенному имени хоста.
Но клиент не проверяет, точно ли данный сертификат является именно тем сертификатом, который использует Ваш сервер. Сопоставление клиентом SSL сертификатов, которые находятся в хранилище доверенных сертификатов устройства, и тех, которые используются на удаленном сервере, открывает потенциальную дыру в безопасности. Хранилище сертификатов на устройстве можно легко скомпрометировать: пользователь может установить небезопасный сертификат и тем самым допустить вероятные MITM-атаки (атака «человек посередине»).
SSL pinning или пиннинг SSL сертификата – решение этой проблемы. Certificate pinning – это внедрение SSL сертификата, который используется на сервере, в код мобильного приложения. В этом случае приложение будет игнорировать хранилище сертификатов устройства, полагаясь только на свое хранилище и позволяя создать защищенное SSL соединение с хостом, подписанным только сертификатом, что хранится в самом приложении. Pinning SSL сертификата также позволяет создавать доверительное соединение с сервером, на котором установлен
самоподписанный SSL сертификат без необходимости устанавливать дополнительный сертификат на устройстве пользователя.
Преимущество SSL pinning
Certificate pinning повышает безопасность, ведь с SSL сертификатом, внедренным в код, приложение становится независимым от хранилища сертификатов устройства. Скомпрометировать базу доверенных сертификатов, добавленную в код самого приложения, не так легко. Для этого злоумышленнику придется декомпилировать приложение, внести в него изменения и потом повторно компилировать. Но после этого он все равно не сможет подписать приложение, используя то же хранилище ключей Android, что и изначальный разработчик приложения.
Недостаток SSL pinning
Допустимость внесения изменений снижается. После внедрения SSL сертификата в код приложения, изменить его уже не так просто. Каждый раз изменяя SSL сертификат, Вам нужно будет выпускать обновление приложения, запускать его на Google Play и надеяться, что пользователи его установят. Тем не менее, если Вы закажете SSL сертификат на максимальный срок действия в три года, Вам придется это делать не так часто.
Как SSL pinning работает на Android?
Процесс пиннинга сертификата на Android состоит из четырех важных шагов:
1.
Приобретите SSL сертификат для хоста, нуждающегося в защите. Как мы уже упомянули, лучше сразу заказать сертификат на несколько лет, чтобы избежать необходимости часто обновлять приложение.
2. Конвертируйте сертификат в формат .bks. Этот шаг очень важен для того, чтобы пиннинг правильно работал на всех устройствах Android. Когда Вы получаете SSL сертификат, он, как правило, находится в формате .crt, .cert или .pem. Чтобы конвертировать его в .bks формат, Вам нужно сначала получить .jar, который содержит Bouncy Castle gj ccskrt, его можно загрузить, например, по следующей ссылке:
http://repo2.maven.org/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.46/bcprov-ext-jdk15on-1.46.jar
Для конвертации используйте следующую команду:
keytool -importcert -v -trustcacerts -file "mycertfile.pem" -alias ca -keystore "keystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-ext-jdk15on-1.46.jar" -storetype BKS -storepass testing
Используйте параметр
-file, чтобы указать формат файла сертификата (.crt, .cert или .pem). Исходящее хранилище ключей обозначено параметром
-keystore. С помощью аргумента
-providerpath следует задать путь к .jar Bouncy Castle. В заключение, пароль к созданному хранилищу ключей задается через параметр
-storepass.
3. Используйте клиент Apache HTTP, который поставляется вместе с ОС Android. Запустите его, чтобы использовать полученное хранилище ключей .bks для SSL соединения. Пример кода для SSL pinning можно найти на страницах
https://github.com/ikust/hello-pinnedcerts и
http://nelenkov.blogspot.ru/2012/12/certificate-pinning-in-android-42.html. Также код для использования SSL pinning для платформ iOS, Android и .NET есть на следующем сайте OWASP (сокращенно от Open Web Application Security Project) -
https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning.
SSL Pinning – это не та процедура, которую нужно проводить для всех приложений, но ее проведение имеет смысл для приложений с высоким риском взлома, которые требуют повышенного уровня безопасности, как, например, приложения мобильного банкинга.