Подписание кода в React Native

Подписание приложений, сертификаты, профиль обеспечения. Если все эти слова вам знакомы, но все еще не имеют никакого смысла, значит, вы попали по адресу. В этой серии статей я постараюсь объяснить концепции, которые остаются за рамками дистрибутива на React Native.

Примечание! Эти концепции не совсем относятся к React Native, они общие для дистрибуции на iOS/Android. Если вы являетесь разработчиком на Java или Swift, эта статья также может пригодиться вам.

Цифровая подпись

Первый шаг, который вам необходимо пройти для публикации приложения в магазинах (Google Play, Apple Store) — это подписать приложение. На iOS это происходит автоматически, на Android мы должны сделать это вручную.

Но что значит «подписать»? Чтобы понять это, нам нужно познакомиться с более общим понятием, которое называется цифровой подписью.

Википедия гласит:

Цифровая подпись — это математическая схема проверки подлинности цифровых сообщений или документов. Действительная цифровая подпись (…) дает получателю очень высокую уверенность в том, что сообщение было создано известным отправителем и что сообщение не было изменено при передаче._

Если вы раньше не сталкивались с концепциями шифрования, вы можете быть озадачены, но не волнуйтесь. Это не так сложно, как может показаться. Давайте разберем все на реальном примере.

Представим, что у меня есть друг и его зовут Боб. Мы хотим приватно обмениваться с ним сообщениями через Интернет. Но есть одна проблема. Интернет — это довольно злобный мир, где все может быть легко перехвачено и изменено. Мы не можем быть уверены, что наши личные сообщения не будут прочитаны или изменены посредником. Чтобы предотвратить эту проблему небезопасности, мы решаем использовать шифрование с Бобом.

С помощью специальной функции мы генерируем уникальные пары ключей для себя. Пара для меня и пара для Боба. Каждая пара содержит две вещи: открытый и закрытый ключ. Они математически связаны друг с другом, поэтому из всего многообразия ключей мира (миллиарды и миллиарды) ключи из одной пары всегда будут «связаны». Это называется асимметричной криптографией.

function pseudoKeyPairGenerator() {
    // ... really hard computation here
    return [privateKey, publicKey]
}

const keysForBob = pseudoKeyPairGenerator();
const keysForMe = pseudoKeyPairGenerator();
Войти в полноэкранный режим Выход из полноэкранного режима

Практически это означает, что открытый ключ есть у всех и каждого. Вам не стоит беспокоиться о том, что его могут украсть или взломать. Люди будут использовать ваш открытый ключ для шифрования сообщений, предназначенных именно вам, но никому другому. В свою очередь, закрытый ключ — это секрет, который вы должны хранить в глубоком секретере и использовать его только для расшифровки сообщений после получения. Если вы потеряете закрытый ключ, веб-злодеи могут скомпрометировать вашу личность, отправляя/читая сообщения от вашего имени. Это нарушит правило неотказов, согласно которому разработчик не может отрицать, от кого/куда пришло сообщение. Всегда помните об этом и храните закрытый ключ как можно надежнее.

Давайте вернемся к Бобу и попробуем обменяться сообщениями, используя полученную информацию:

  1. Мы обмениваемся нашими открытыми ключами. У Боба есть мой, у меня — его.
  2. Я написал сообщение и зашифровал его с помощью открытого ключа Боба. Затем я отправляю сообщение.
  3. Боб получает зашифрованное сообщение. Он знает, что оно предназначено ему, и никто не может изменить/прочитать сообщение, потому что только он владеет второй парой. С помощью своего закрытого ключа Боб расшифровывает сообщение и, наконец, читает его.

Поздравляем! Теперь вы понимаете, как работает цифровая подпись с точки зрения основ криптографии. Но как это связано с подписанием кода?

Подписание кода

Мы узнали, что специальная пара криптографических ключей позволяет нам зашифровать/расшифровать сообщение и отправить его без риска, что сообщение может быть подделано. Эта идея защиты очень эффективна и может быть применена и для кода. Это поможет получателю (пользователю приложения) быть полностью уверенным в том, что код (наше приложение) пришел от ожидаемой личности и не был изменен, или, другими словами, взломан с помощью вредоносного кода для кражи данных пользователя. Где-то в этом потоке загрузки/выгрузки наши ключи все еще существуют для защиты нашего приложения, так что все звучит довольно просто, верно?

Но в Code Signing названия ключей и принцип их работы отличаются. Вместо открытых и закрытых ключей в системе распространения Google (Android) есть ключи загрузки и подписи. В этом случае их роль заключается только в шифровании данных без возможности расшифровки.

Что касается Apple (iOS), то подписание кода происходит автоматически после создания профиля обеспечения, о котором мы поговорим в следующей статье.

  • Ключ загрузки мы генерируем на нашей локальной машине и используем для подписи пакета/APK, который мы загружаем в Google Play. С помощью этого ключа Google проверяет нашу личность. Если вы потеряли ключ, вы можете связаться с Google, чтобы отозвать старый ключ загрузки и сгенерировать новый, чтобы вы могли продолжать загружать новые версии своего приложения.

  • Ключ подписи создается компанией Google и используется для подписи окончательной версии приложения, когда пользователь загружает его из магазина Google Play. Вы не можете потерять ключ, если только не попытаетесь сохранить его самостоятельно, что не рекомендуется, поскольку, потеряв его, вы навсегда потеряете доступ к своему приложению.

Основная идея разделения закрытого ключа на два отдельных заключается в том, что Google получает ответственность за шифрование процессов и облегчает жизнь разработчикам (сложнее изменить код, потерять доступ к приложению). Мы не должны бояться потерять секретный ключ/ключ подписи и быть скомпрометированными впоследствии.

Еще раз. Своей цифровой подписью, которая является ключом подписи, мы доказываем Google, что мы — это мы (разработчик приложения). Со своей стороны, Google с помощью ключа подписи завершает шифрование приложения и предоставляет его конечному пользователю в виде упакованной программы, которая не могла быть изменена. Эта цепочка действий создает доверие к достоверности приложения, и это называется подписью кода.

Надеюсь, теперь все встало на свои места. В последней главе рассмотрим, как сгенерировать подписанный APK.

Генерация ключей и APK

Чтобы загрузить приложение в Play Market, нам нужно сгенерировать релизный APK и подписать его ключом загрузки. Ключ загрузки появляется, когда мы создаем файл keystore с помощью keytool. Keystore — это двоичный файл, который служит хранилищем сертификатов и закрытых ключей.

Перейдите в android/app и используйте следующую команду для создания keystore:

keytool -genkeypair -v -storetype PKCS12 -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
Войти в полноэкранный режим Выйти из полноэкранного режима

Как вы уже знаете, файл keystore должен быть приватным. Не передавайте его никому.

Следующая часть — это установка переменных Gradle в android/gradle.properties. Данные для переменных мы берем из значений, которые недавно использовали при создании keystore.

MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=*****
MYAPP_UPLOAD_KEY_PASSWORD=*****
Вход в полноэкранный режим Выход из полноэкранного режима

Последний шаг конфигурации, который необходимо выполнить, это настроить подписание релизных сборок с помощью ключа загрузки. Отредактируйте файл android/app/build.gradle в папке вашего проекта и добавьте конфиг подписания. Переменная будет взята из предыдущего отредактированного файла.

android {
    ...
    defaultConfig { ... }
    signingConfigs {
        debug { ... }
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword MYAPP_UPLOAD_STORE_PASSWORD
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword MYAPP_UPLOAD_KEY_PASSWORD
            }
        }
    }
    buildTypes {
        debug { ... }
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Если вы хотите сгенерировать APK-файл для целей тестирования (прямой установки), вы можете сделать это, выполнив следующую команду:

./gradlew assembleRelease

/* 
    located in
    android/app/build/outputs/apk/release/app-release.apk
*/
Войти в полноэкранный режим Выйти из полноэкранного режима

Если вы хотите загрузить приложение в Google Play, рекомендуется сгенерировать файл AAB. Как и при создании APK, вы используете ту же команду, но заменяете assemble на bundle, как показано ниже:

./gradlew bundleRelease

/* 
    located in
    android/app/build/outputs/bundle/release/app-release.aab
*/
Вход в полноэкранный режим Выйти из полноэкранного режима

Обзор

Подписание кода — это процесс цифровой подписи исполняемых файлов для подтверждения автором программного обеспечения того, что код не был изменен или поврежден с момента подписания. Это позволяет магазинам легко определить личность издателя и обеспечивает доверие для пользователя приложения.

Источники

  • React Native (публикация)
  • Android Studio (подписание приложений)
  • Справочник Infinum
  • KD CyberTalks

Оцените статью
devanswers.ru
Добавить комментарий