Одним из наиболее важных аспектов разработки программного обеспечения, который также считается одним из самых загадочных и страшных (и поэтому его избегают, как чумы), является безопасность приложений.
Пользователи ожидают, что их приложения будут работать правильно, хранить их личную информацию и защищать эту информацию от потенциальных угроз.
В этой статье вы погрузитесь в основы безопасности в iOS. Вы поработаете с некоторыми базовыми методами криптографического хеширования для безопасного хранения полученных данных в связке ключей, сохраняя и защищая пользовательские данные внутри приложения.
У Apple есть несколько API-интерфейсов, которые помогут защитить ваши приложения, и вы изучите их, работая с Keychain. Кроме того, вы будете использовать CryptoSwift — иметь хорошее представление и обзор библиотеки с открытым исходным кодом, реализующей криптографические алгоритмы.
Начинать
Использовать это связь скачать проект для работы.Мы будем работать над приложением, которое позволит пользователям регистрироваться и просматривать фотографии своих друзей.
Большая часть приложения уже реализована, ваша задача — защитить это приложение.
После распаковки архива обязательно откройте файл Friendvatars.xcworkspace, чтобы включить зависимости с помощью CocoaPod. Скомпилируйте и запустите приложение.
Вы увидите, что он начинается с экрана входа в систему:
В настоящее время, когда вы нажимаете кнопку Войти Ничего не произошло.
Это связано с тем, что приложение не имеет возможности хранить учетные данные пользователя.
Это то, что вам нужно будет добавить в первую очередь.
Почему важна безопасность
Прежде чем погрузиться в кодирование, вы должны понять, почему в вашем приложении необходима безопасность.Безопасность вашего приложения особенно важна, если вы храните личные данные пользователя, такие как адреса электронной почты, пароли или информацию о банковском счете.
Почему Apple так серьезно относится к безопасности? Ваш iPhone хранит много личных данных: от фотографий, которые вы делаете, до количества шагов, которые вы делаете в течение дня.
Защита этих данных очень важна.
Кто такие злоумышленники в экосистеме iOS и чего они хотят? Злоумышленником может быть преступник, конкурент по бизнесу или даже друг или родственник.
Не все злоумышленники хотят одного и того же.
Некоторые, возможно, захотят нанести ущерб или испортить информацию, а другие, возможно, захотят узнать, какие подарки они получат на свой день рождения.
Ваша задача — убедиться, что данные, хранящиеся в вашем приложении, защищены от возможных угроз.
К счастью, Apple разработала множество мощных API, которые облегчают эту задачу.
Брелок
Одним из наиболее важных элементов безопасности для разработчиков iOS является Брелок , специализированная база данных для хранения метаданных и конфиденциальной информации.Использование «Связки ключей» — лучший способ хранения небольших фрагментов данных, важных для вашего приложения, таких как секреты и пароли.
Зачем использовать Keychain для более простых решений? Достаточно ли хранить пароль пользователя в база-64 В Пользовательские значения по умолчанию ? Точно нет! Злоумышленнику довольно просто восстановить сохраненный таким образом пароль.
Безопасность сложна, и пытаться создать собственное решение — не лучшая идея.
Даже если ваше приложение не для финансового учреждения, к хранению персональных данных пользователей не следует относиться легкомысленно.
Прямое взаимодействие с Keychain довольно сложно, особенно в Swift. Вы должны использовать Системы безопасности , которые в основном написаны на C.
К счастью, вы можете избежать использования этих низкоуровневых API, позаимствовав пример оболочки Swift от Apple. Универсальный брелок .
БрелокПарольЭлемент предоставляет простой в использовании интерфейс для работы с Keychain и уже включен в стартовый проект.
Время погрузиться в код!
Использование связки ключей
Открыть AuthViewController.swift .Этот контроллер отвечает за форму входа, которую вы видели вначале.
Если вы зайдете в раздел Действия , вы заметите, что метод ВойтиВКнопкаНажата ничего не делать.
Пришло время это исправить.
Добавьте следующий код в раздел Помощники внизу:
Вот как это происходит:private func signIn() { // 1 view.endEditing(true) // 2 guard let email = emailField.text, email.count > 0 else { return } guard let password = passwordField.text, password.count > 0 else { return } // 3 let name = UIDevice.current.name let user = User(name: name, email: email) }
- Вы снимаете клавиатуру, чтобы подтвердить, что действие пользователя выполнено.
- Вы принимаете адрес электронной почты и пароль пользователя.
Если длина введенной информации в поле равна нулю, то функция не продолжит выполнение.
В реальном приложении вы должны показать пользователю ошибку.
- Вы назначаете имя пользователя, которое в учебных целях в этой статье берется из имени устройства.
Вы можете изменить имя вашего Mac (которое используется SIM-картой), перейдя в Системные настройки -> Общий доступ .
Кроме того, вы можете изменить имя своего iPhone, перейдя в Настройки -> Общие -> О программе -> Имя .
Теперь добавьте следующее в метод SignInButtonPressed: signIn()
Этот код вызывает метод SignIn при выполнении SignInButtonPressed.
Находить textFieldShouldReturn и заменить TextFieldTag.password.rawValue В перерыв под случай к следующему: signIn()
Теперь метод войти() будет вызываться, когда пользователь нажимает клавишу Return на клавиатуре после того, как он ввел текст в поле пароля, в то время как поле пароля находится в фокусе и уже содержит текст.
Метод войти() еще не реализована в полной мере.
Нам все еще нужно хранить объекты пользователя и пароля.
Все это будет реализовано во вспомогательном классе.
Открыть AuthController.swift , который является статическим классом и будет содержать бизнес-логику, связанную с аутентификацией.
Для начала в самом верху файла выше isSignedIn следует добавить следующее: static let serviceName = "FriendvatarsService"
Этот код определяет имя службы, которая будет использоваться для идентификации данных приложения в связке ключей.
Чтобы использовать эту константу, создайте метод войти в конце урока: class func signIn(_ user: User, password: String) throws {
try KeychainPasswordItem(service: serviceName, account: user.email).
savePassword(password)
Settings.currentUser = user
}
Этот метод позволит надежно сохранить информацию для авторизации пользователей в Связке ключей.
Он создает БрелокПарольЭлемент с названием службы, которую вы определили, а также уникальным идентификатором (учетной записью).
В этом приложении адрес электронной почты пользователя используется в качестве идентификатора Keychain, но другие данные также могут служить идентификатором или уникальным именем пользователя.
Наконец, в Settings.currentUser установлено значение user — все это хранится в Пользовательские значения по умолчанию .
Этот метод не следует считать законченным! Сохранение пароля пользователя напрямую не рекомендуется.
Например, если злоумышленник взломал Keychain, он сможет получить пароли каждого пользователя в виде обычного текста.
Лучшее решение — хранить хэш пароля, построенный на основе личности пользователя.
На вершине AuthController.swift сразу после импортный фонд добавьте следующее import CryptoSwift
КриптоСвифт — одна из самых популярных коллекций многих стандартных криптографических алгоритмов, написанных на Swift. Криптография сложна, и ее нужно делать правильно, чтобы она была по-настоящему полезной.
Использование популярной библиотеки безопасности означает, что вы не несете ответственности за реализацию стандартизированных функций хеширования.
Лучшие методы криптографии открыты для всеобщего обозрения.
Примечание: Платформа CommonCrypto от Apple предоставляет множество полезных функций хеширования, но с ними нелегко работать в Swift. Вот почему для этой статьи мы выбрали библиотеку CryptoSwift.
Затем добавьте следующий код выше войти : class func passwordHash(from email: String, password: String) -> String {
let salt = "x4vV8bGgqqmQwgCoyXFQj+(o.nUNQhVP7ND"
return "\(password).
\(email).
\(salt)".
sha256()
}
Этот метод принимает адрес электронной почты и пароль и возвращает хешированную строку.
Солт-константа — это уникальная строка, которая превращает обычный пароль в редкий.
.
sha256() - это метод из фреймворка КриптоСвифт , который хэширует входную строку с помощью алгоритма ША-2 .
В предыдущем примере злоумышленник, взломавший Keychain, нашел бы этот хэш.
Злоумышленник может создать таблицу часто используемых паролей и их хэшей для сравнения с этим хешем.
Если вы хешировали только вводимые пользователем данные без использования соли, а пароль существовал в хеш-таблице злоумышленников, пароль мог быть скомпрометирован.
Применение соль увеличивает сложность взлома.
Кроме того, вы объединяете адрес электронной почты и пароль пользователя с солью, чтобы создать хеш, который нелегко взломать.
Примечание: Для аутентификации пользователя мобильное приложение и сервер будут использовать один и тот же соль .
Это позволяет им единообразным образом создавать хеши и сравнивать два хеша для проверки идентичности.
Вернуться к методу Войти(_:пароль:) , замените строку кода, вызывающую метод Сохраните пароль к следующему: let finalHash = passwordHash(from: user.email, password: password)
try KeychainPasswordItem(service: serviceName, account: user.email).
savePassword(finalHash)
войти теперь хранит надежный хэш, а не необработанный пароль.
Теперь пришло время добавить его в контроллер представления.
Вернуться к AuthViewController.swift и добавьте в конец метода войти() этот код: do {
try AuthController.signIn(user, password: password)
} catch {
print("Error signing in: \(error.localizedDescription)")
}
Несмотря на то, что этот код сохраняет пользователя и хешированный пароль, приложению потребуется что-то еще для входа в систему.
AppController.swift должен получать уведомления при изменении аутентификации.
Возможно, вы заметили, что AuthController.swift имеет статическую переменную с именем isSignedIn .
В настоящее время он всегда возвращает false, даже если пользователь вошел в систему.
В AuthController.swift изменять isSignedIn : static var isSignedIn: Bool {
// 1
guard let currentUser = Settings.currentUser else {
return false
}
do {
// 2
let password = try KeychainPasswordItem(service: serviceName, account: currentUser.email).
readPassword()
return password.count > 0
} catch {
return false
}
}
Вот что здесь происходит:
- Вы немедленно проверяете текущего пользователя, сохраненного в Пользовательские значения по умолчанию .
Если пользователя не существует, то и идентификатор для поиска хеша пароля в Связке ключей также будет отсутствовать, поэтому вы указываете, что он не зарегистрирован в системе.
- Вы получаете хэш пароля от Брелок , и если пароль существует и не пуст, пользователь считается зарегистрированным.
Но есть хороший способ уведомить приложение об изменениях состояния, например аутентификацию пользователя, с помощью уведомления.
Добавьте следующее в конец AuthController.swift : extension Notification.Name {
static let loginStatusChanged = Notification.Name("com.razeware.auth.changed")
}
Хорошей практикой является использование идентификатора домена при составлении пользовательских уведомлений, который обычно берется из идентификатор пакета Приложения.
Использование уникального идентификатора может помочь при отладке вашего приложения, чтобы все, что связано с вашим уведомлением, выделялось среди других платформ, упомянутых в ваших журналах.
Чтобы использовать заданное имя пользовательского уведомления, добавьте следующее в конец метода Войти(_:пароль:) : NotificationCenter.default.post(name: .
loginStatusChanged, object: nil)
Этот код отправит уведомление, которое может быть обнаружено другими частями приложения.
Внутри AppController.swift добавить метод в этом выше показать(в:) : init() {
NotificationCenter.default.addObserver(
self,
selector: #selector(handleAuthState),
name: .
loginStatusChanged,
object: nil
)
}
Этот код будет зарегистрирован AppController в качестве руководителя вашего регистрационного имени.
При срабатывании он вызывает вызовAuthState .
Скомпилируйте и запустите приложение.
После входа в систему с использованием любой комбинации электронной почты и пароля вы увидите список друзей:
Вы заметите, что здесь нет аватаров, только имена друзей.
На это не очень приятно смотреть.
Вероятно, вам следует выйти из этого незавершенного приложения и забыть о нем.
Ах да, даже кнопка выхода не работает. Пришло время дать ему оценку в 1 звезду и по-настоящему вернуть это приложение разработчику!
Логгирование работает нормально, но выйти из приложения невозможно.
На самом деле этого довольно легко добиться, поскольку существует уведомление, которое будет сигнализировать об изменении состояния аутентификации.
Вернуться к AuthViewController.swift и добавьте следующее в разделе Войти(_:пароль:) : class func signOut() throws {
// 1
guard let currentUser = Settings.currentUser else {
return
}
// 2
try KeychainPasswordItem(service: serviceName, account: currentUser.email).
deleteItem() // 3 Settings.currentUser = nil NotificationCenter.default.post(name: .
loginStatusChanged, object: nil)
}
Это довольно просто:
- Вы проверяете, сохранили ли вы текущего пользователя или нет, если вы не сделали этого раньше.
- Вы удаляете хэш пароля из связки ключей.
- Вы очищаете объект пользователя и отправляете уведомление.
try? AuthController.signOut()
Ваш новый метод вызывается для очистки данных вошедшего в систему пользователя при нажатии кнопки «Выход».
Устранение ошибок в приложении — хорошая идея, но ради этого руководства игнорируйте любые ошибки.
Скомпилируйте и запустите приложение, затем нажмите кнопку «Выход».
Теперь у вас есть полноценный рабочий пример аутентификации в приложении!
Хеширование
Вы отлично справились с созданием аутентификации! Однако веселье еще не закончилось.Теперь вы преобразуете это пустое пространство перед именами в списке друзей.
В FriendsViewController.swift отображается список объектов модели пользователя.
Вы также хотите отображать изображения аватаров для каждого пользователя в представлении.
Поскольку у пользователя есть только два атрибута: имя и адрес электронной почты, как вы собираетесь отображать изображение? Оказывается, есть сервис, который берет адрес электронной почты и связывает его с изображением аватара: Граватар ! Если вы еще не слышали о Gravatar, он обычно используется в блогах и на форумах для глобальной связи адреса электронной почты с аватаром.
Это упрощает работу, так что пользователям не нужно загружать новый аватар на каждый форум или сайт, к которому они присоединяются.
У каждого из этих пользователей уже есть аватар, связанный с его электронной почтой.
Поэтому единственное, что вам нужно сделать, это запросить Gravatar и получить изображения от запрошенных пользователей.
Для этого вы создадите MD5 хешировать свою электронную почту для создания URL-запросов.
Если вы посмотрите документацию на сайте Gravatar, вы увидите, что для создания запроса вам нужен хешированный адрес электронной почты.
Это будет проще простого, так как вы можете использовать КриптоСвифт .
Добавьте Граватар вместо комментариев tableView(_:cellForRowAt:) следующий: // 1
let emailHash = user.email.trimmingCharacters(in: .
whitespacesAndNewlines) .
lowercased() .
md5() // 2 if let url = URL(string: " https://www.gravatar.com/avatar/ " + emailHash) { URLSession.shared.dataTask(with: url) { data, response, error in guard let data = data, let image = UIImage(data: data) else { return } // 3 self.imageCache.setObject(image, forKey: user.email as NSString) DispatchQueue.main.async { // 4 self.tableView.reloadRows(at: [indexPath], with: .
automatic) } }.
resume()
}
Давайте посмотрим на это:
- Сначала вы форматируете адрес электронной почты в соответствии с документацией Gravatar, а затем создаете хеш.
MD5 .
- Вы создаете URL-адрес Gravatar и URL-сессия .
Вы загружаете UIImage из возвращенных данных.
- Вы кэшируете изображение, чтобы избежать повторной загрузки по адресу электронной почты.
- Вы сбрасываете строку в представлении таблицы, чтобы отобразить изображение аватара.
Теперь вы можете видеть фотографии и имена своих друзей:
Примечание: Если в вашем электронном письме возвращается изображение по умолчанию (белое на синем G), перейдите на сайт Gravatar, загрузите свой собственный аватар и присоединяйтесь к друзьям!
Если вас интересуют другие способы защиты ваших приложений, изучите использование биометрических датчиков в последних продуктах Apple в этом разделе.
статья .
Вы также можете узнать больше о и Инфраструктура безопасности Apple , если вы хотите действительно заглянуть в структуру.
В конце обязательно изучите дополнительные алгоритмы безопасности предоставлено CryptoSwift. Надеюсь, вам понравилась эта статья! Если у вас есть какие-либо вопросы или комментарии, присоединяйтесь к обсуждению! Теги: #Связка ключей и хеширование #iOS #разработка iOS #Swift #безопасность #безопасность данных #безопасность данных #objective-c #информационная безопасность #разработка iOS #Разработка мобильных приложений #Swift
-
Агентство Ppc Для Продвижения Вашего Бизнеса
19 Oct, 24 -
Ассоциативная Память
19 Oct, 24 -
2D Скролл-Шутер За Неделю
19 Oct, 24