Могу ли я указать алгоритм дайджеста, который использует apksigner?

Из-за недавних новостей о коллизиях SHA1 я хочу убедиться, что SHA1 больше не используется в моей подписи apk. Однако я не могу найти параметр в apksigner.

Есть ли способ указать (прямой или косвенный) алгоритм дайджеста, который использует apksigner?

(До SDK 24 Android использовал Java jarsigner подписать apk, который имеет такие параметры, как -sigalg SHA1withRSA -digestalg SHA1)


Обновление: как уже упоминал Алекс, я нашел, как apksigner определить алгоритм подписи для схемы v1 в V1SchemeSigner.java.

Короче, apksigner определить это от minimumSDK и тип ключа сертификата.

  • SHA256withRSA для минимум SDK 18 (Android 4.3) и выше
  • SHA256withDSA для минимум SDK 21 (Android 5.0) и выше
  • SHA256withEC для минимум SDK 18 и выше
  • SHA1with* для более низких минимальных уровней SDK

Это FAQ, который я написал для заметки: SHA1 Collision и Android APK Signing.

2 ответа

Решение

Не напрямую. apksigner пытается использовать только безопасные дайджесты и алгоритмы подписи, но делает это в рамках ограничений, накладываемых вашим ключом подписи (размер, алгоритм) и версиями платформы Android, поддерживаемыми подписываемым APK. В частности, для подписей JAR, apksigner по умолчанию использует SHA-256 или более сильный, но только для APK, которые поддерживают только API уровня 18 или новее (как объявлено в minSdkVersion в их AndroidManifest.xml). APK, которые работают на более ранних платформах, должны использовать SHA-1, потому что эти более ранние платформы не поддерживают проверку APK с использованием SHA-256 или более поздней версии. Для подписи APK Signature Scheme v2 используется только SHA-256 или более поздняя версия, поскольку эта схема подписи даже не поддерживает SHA-1.

Если ты хочешь apksigner Чтобы подписать свой APK с SHA-256, вы можете:

  • Установите APK minSdkVersion до 18 или выше, но это приведет к тому, что платформы Android с уровнем API 17 и ниже будут отклонять APK во время установки.
  • Пройти в --min-sdk-version=18 в apksigner, но это приведет к тому, что платформы Android с уровнем API 17 и ниже будут отклонять APK во время установки.
  • Подпишите APK только с помощью APK Signature Scheme v2, передав --v1-signing-enabled=false в apksigner, но это приведет к тому, что платформы Android с уровнем API 23 и ниже будут отклонять APK во время установки.

PS Даже если вы перешли к подписанию ваших APK с помощью только SHA-256, Android все равно будет принимать APK с вашим именем пакета и сертификатом подписи, подписанным с помощью SHA-1 или MD5. Поэтому, в зависимости от вашей модели угроз, вам может потребоваться перейти на новые подписывающие ключи, которые никогда не использовались с SHA-1, или более слабые алгоритмы дайджеста. И это не только для алгоритма дайджеста, используемого в реальной криптографической подписи, но также и для алгоритмов дайджеста, используемых в .SF а также MANIFEST.MF файлы.

В своих экспериментах я увидел, что бывают ситуации, когда невозможно сapksigner. Моя среда:

  • Инструменты сборки Android SDK v33.0.1
  • JKS с самоподписанным сертификатом RSA 4096 бит с SHA1
  • OpenJDK 1.8.0_352

Даже если я поставлю--min-sdk-version 28, я всегда получаю сертификат с подписью RSA с SHA1.

Но это ничего не меняет — потому что Android ожидает точно такой же сертификат для работы обновлений приложений. В моих экспериментах изменение алгоритма дайджеста делало сертификат другим, и обновления не работали. (ссылки: https://stackoverflow.com/a/74931130/1961303 )

Таким образом, кажется, что остался один вариант удаления SHA1: ротация ключей APK из Android 9 (ссылки: https://developer.android.com/about/versions/pie/android-9.0#apk-key-rotation )

Другие вопросы по тегам