Рубрики
Без рубрики

Сертификат, закрепляющий ваши приложения для Android и iOS.

Когда мы, разработчики, работаем над разработкой любого вида программного обеспечения, мы не можем забывать об этом… С тегами android, ios, java, swift.

Когда мы, разработчики, работаем над разработкой любого вида программного обеспечения, мы не можем забывать о безопасности 🔐 . Минимальная мера безопасности, которую мы должны использовать, – это HTTPS в качестве протокола для обмена информацией между клиентом (в данном случае приложением для Android/iOS) и сервером, за которым следует обновленный криптографический протокол, такой как TLS 1.2 (SSL 3.0 уязвим!) Вы можете подумать, что достаточно использовать HTTPS, но в некоторых случаях, таких как банковские приложения, где конфиденциальные данные могут передаваться между нашим клиентом и нашим сервером, это может быть рискованно. По умолчанию при установлении соединения TLS клиент проверяет две вещи:

  1. Сертификат сервера соответствует запрошенному имени хоста.
  2. Сертификат сервера имеет цепочку достоверности, ведущую к доверенному корневому сертификату.

Чего он не делает, так это проверяет, является ли сертификат тем конкретным сертификатом, который, как вы знаете, использует ваш сервер, и это возможная уязвимость в системе безопасности: если клиент скомпрометирован и установлен небезопасный сертификат, кто-то может совершить атаку “человек посередине”.

Решением этой проблемы является закрепление сертификата: хранение сертификата на нашем клиенте, чтобы гарантировать, что любой сделанный SSL-запрос соответствует тому, который есть у нашего сервера. Позвольте мне объяснить вам, как это сделать как в приложениях для Android, так и в приложениях для iOS.

Андроид

OkHttp lib предоставляет класс CertificatePinner для добавления в экземпляр OkHttpClient. Самый простой способ закрепить хост – это включить закрепление с поврежденной конфигурацией и прочитать ожидаемую конфигурацию при сбое соединения.

CertificatePinner certificatePinner = new CertificatePinner.Builder()
         .add("mydomain.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
         .build();
     OkHttpClient client = OkHttpClient.Builder()
         .certificatePinner(certificatePinner)
         .build();

После выполнения запроса вы увидите это сообщение на консоли:

javax.net.ssl.SSLPeerUnverifiedException: Certificate pinning failure!
   Peer certificate chain:
     sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=: CN=mydomain.com, OU=PositiveSSL
     sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=: CN=COMODO RSA Secure Server CA
     sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=: CN=COMODO RSA Certification Authority
     sha256/lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=: CN=AddTrust External CA Root
   Pinned certificates for mydomain.com:
     sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
   at okhttp3.CertificatePinner.check(CertificatePinner.java)
   at okhttp3.Connection.upgradeToTls(Connection.java)
   at okhttp3.Connection.connect(Connection.java)
   at okhttp3.Connection.connectAndSetOwner(Connection.java)

Исключение предоставит вам хэши открытого ключа сертификата сервера. Вставьте их в Certificatepinner и готово! ✔

CertificatePinner certificatePinner = new CertificatePinner.Builder()
       .add("mydomain.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
       .add("mydomain.com", "sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=")
       .add("mydomain.com", "sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=")
       .add("mydomain.com", "sha256/lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=")
       .build();

iOS

Решение для iOS не так просто, потому что вам нужно сохранить сам сертификат внутри вашего приложения. В моем случае я использовал Alamofire в качестве библиотеки HTTP-клиента для Swift. Во-первых, вам нужно получить сертификат сервера в .der отформатируйте и добавьте его в свой проект iOS.

openssl s_client -showcerts -servername mydomain.com -connect mydomain.com:443
  mydomainCert.der

А теперь давайте включим закрепление сертификата: для этого нам понадобятся объекты ServerTrustPolicy и Session Manager. Первый из них определит имя хоста и сертификаты, которые будут использоваться в процессе:

var serverTrustPolicies = [
    "mydomain.com": .pinCertificates(
    certificates: ServerTrustPolicy.certificates(),
    validateCertificateChain: true,
    validateHost: true
  ),
]

ServerTrustPolicy.certificates() вернет все сохраненные сертификаты, а логические значения проверят цепочку сертификатов и имя хоста. Наконец, создайте объект SessionManager, используя эту политику доверия:

var sessionManager = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies!))

Сделано! ✔. Просто используйте этот объект SessionManager для выполнения запроса

sessionManager.request("https://mydomain.com/api", method: .get, headers: headers)...

Обратная связь приветствуется! Надеюсь, это будет полезно ☺️

Источники

OkHttp: https://github.com/square/okhttp/wiki/HTTPS Аламофайр: Аламофайр:

Оригинал: “https://dev.to/drankolq/certificate-pinning-your-android-and-ios-apps”