我在签署 Android 应用程序包时收到以下消息:
Signing file D:/dev/repos/examples/src/MyApp/build-MyAppQt-Android_Qt_6_6_0_arm64_v8a_release_Clang_arm64_v8a-Release/android-build//build/outputs/bundle/release/android-build-release.aab
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v3.1 scheme (APK Signature Scheme v3.1): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
WARNING: META-INF/com/android/build/gradle/app-metadata.properties not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.activity_activity.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.annotation_annotation-experimental.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.appcompat_appcompat-resources.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.appcompat_appcompat.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.arch.core_core-runtime.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.browser_browser.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.core_core-ktx.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.core_core.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.cursoradapter_cursoradapter.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.customview_customview.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.datastore_datastore.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.drawerlayout_drawerlayout.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.fragment_fragment.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.interpolator_interpolator.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.lifecycle_lifecycle-livedata-core.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.lifecycle_lifecycle-livedata.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.lifecycle_lifecycle-runtime.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.lifecycle_lifecycle-service.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.lifecycle_lifecycle-viewmodel.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.loader_loader.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.privacysandbox.ads_ads-adservices-java.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.privacysandbox.ads_ads-adservices.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.recyclerview_recyclerview.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.room_room-runtime.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.savedstate_savedstate.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.sqlite_sqlite-framework.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.sqlite_sqlite.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.startup_startup-runtime.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.tracing_tracing.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.transition_transition.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.vectordrawable_vectordrawable-animated.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.vectordrawable_vectordrawable.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.versionedparcelable_versionedparcelable.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.viewpager2_viewpager2.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.viewpager_viewpager.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/androidx.work_work-runtime.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/com.google.dagger_dagger.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
WARNING: META-INF/kotlinx_coroutines_core.version not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
Android package built successfully in 97.909 ms.
-- File: D:/dev/repos/examples/src/MyApp/build-MyAppQt-Android_Qt_6_6_0_arm64_v8a_release_Clang_arm64_v8a-Release/android-build//build/outputs/apk/release/android-build-release-signed.apk
忽略它们并在 Google Play 上发布应用程序是否安全?
为什么此文件没有签名?
我的
build.gradle
:
buildscript {
ext.kotlin_version = '1.8.0'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.1'
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
}
}
repositories {
google()
mavenCentral()
}
apply plugin: 'com.android.application'
dependencies {
// implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation 'com.yandex.android:mobileads:6.2.0'
implementation 'com.yandex.ads.mediation:mobileads-google:22.4.0.0'
// implementation 'com.google.android.gms:play-services-ads:21.5.0'
implementation "com.android.billingclient:billing:6.0.1"
// From the template
implementation 'androidx.core:core:1.10.1'
}
android {
/*******************************************************
* The following variables:
* - androidBuildToolsVersion,
* - androidCompileSdkVersion
* - qtAndroidDir - holds the path to qt android files
* needed to build any Qt application
* on Android.
*
* are defined in gradle.properties file. This file is
* updated by QtCreator and androiddeployqt tools.
* Changing them manually might break the compilation!
*******************************************************/
//androiddeployqt.exe fails without package attribute in the mainifest.
//namespace 'net.geographx.LinesGame'
compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion
ndkVersion androidNdkVersion
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = [qtAndroidDir + '/src', 'src', 'yandex-ad-src', 'java']
aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl']
res.srcDirs = [qtAndroidDir + '/res', 'res']
resources.srcDirs = ['resources']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
tasks.withType(JavaCompile) {
options.incremental = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// From the template
// Extract native libraries from the APK
packagingOptions.jniLibs.useLegacyPackaging true
lintOptions {
abortOnError false
}
// Do not compress Qt binary resources file
aaptOptions {
noCompress 'rcc'
}
defaultConfig {
minSdkVersion qtMinSdkVersion
targetSdkVersion qtTargetSdkVersion
ndk.abiFilters = qtTargetAbiList.split(",")
//For debug builds native-debug-symbols.zip size is 432MB.
//Use SYMBOL_TABLE to upload debug builds.
ndk.debugSymbolLevel "FULL"
}
//The build type becomes release when we sign the bundle,
//otherwize the build type is debug with both Debug and RelWithDebInfo.
//With SYMBOL_TABLE we have .sym in native-debug-symbols.zip and
//with FULL we have .dbg.
/*
buildTypes {
release {
//Full debug for uploading production and beta builds.
ndk.debugSymbolLevel "FULL"
}
debug {
//Small debug info for uploading internal testing builds.
ndk.debugSymbolLevel "SYMBOL_TABLE"
}
}
*/
}
我不确定确切的签名命令是什么,因为 QT 创建者没有在构建日志中显示它。
您遇到的警告仅适用于 APK 签名 v1,但由于 APK 文件还包含 v2 和 v3 签名,您可以安全地忽略此消息,因为 APK 文件上的每个修改都可以被较新的签名方案检测到。
但是,即使可以验证签名,也不意味着APK文件是正版的。修改后仍然可能会被撤销,因此您应该仔细比较待验证APK的证书摘要(使用
apksigner verify --verbose --print-certs
验证时显示),并将其与同一应用程序开发者的其他APK文件进行比较。请参阅如何验证我下载的 APK 文件的真实性?的答案,了解如何比较 APK 的证书摘要的详细信息。
首先,正如您所看到的,您得到的是警告而不是错误。如果 APK 文件的相关文件已被修改,验证将失败,并且您将收到一条错误消息。
要理解警告消息,您需要对 Java 以及 Java 签名(APK 签名 v1)的工作原理有一点了解。此旧签名存储在 JAR 内的两个文件中:
META-INF/CERT.SF
和 META-INF/CERT.RSA
。当然,签名无法对其写入的文件进行签名,因此这些文件被签名排除在外。
此外,META-INF 目录是
MANIFEST.MF
的位置 - 该文件仅与桌面上的 Java 相关,但 Android 根本不使用。
META-INF 目录中可以有其他文件,考虑到标准 Java 目录布局,不应将代码存储在 META-INF 目录内的文件内。
正因为如此,Sun 作为 Java 的原始发明者决定从 Java 代码签名中完全排除 META-INF 目录。几年后,Google 仅对 APK 文件使用 Java 签名,现在称为 APK 签名 v1。
因此对于APK签名v1来说,META-INF目录中的文件不会被签名覆盖,因此只要验证就可以修改而不被识别
由于对 APK 签名本身的多次攻击(例如在 APK 中多次包含具有不同内容的同一文件),Google 决定开发一个全新的 APK 签名,该签名不适用于 APK 内容,而是适用于整个 APK 文件本身。这是 APK 签名 v2 及其后继者的开始。
这些新的 APK 签名方案确实会立即对完整的 APK 内容进行签名,不排除存储在 APK 文件内的单个文件。
返回 Google Podcast APK,使用 apksigner 验证它,输出如下:
java -jar apksigner.jar verify --verbose "Google Podcasts Discover free trending podcasts_v1.0.0.301897054_apkpure.com.apk"
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
WARNING: META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.
如您所见,APK 文件不仅由 v1 签名进行签名,还由 v2、v3 和 v4 签名进行签名。这意味着警告仅适用于 v1 方案创建的签名。您可以通过修改文件中的单个字符来轻松验证
META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader
,因为它未压缩地存储在 APK 文件中。您可以简单地在十六进制编辑器中打开 APK 文件,修改属于该文件的部分中的字符(它是 APK 中的第一个 ZIP 条目),然后再次验证 APK:
java -jar apksigner.jar verify --verbose "Google Podcasts Discover free trending podcasts_v1.0.0.301897054_apkpure.com - modified.apk"
DOES NOT VERIFY
ERROR: APK Signature Scheme v3 signer #1: APK integrity check failed. CHUNKED_SHA256 digest mismatch. Expected: <ac8a15569352655a22f13d3c565c2c0e5c62dc70c8f6f8c10f6fbfa63decb19b>, actual: <aa5622cd904500c38424562ef4b5be9e5716d10a85985a41f35e4ed834cee8fe>
ERROR: APK Signature Scheme v3 signer #1: APK integrity check failed. VERITY_CHUNKED_SHA256 digest mismatch. Expected: <56eeebd545733fd6408cd6a30b8bcf98a557076167902b6d9502b5aca86b78e89b42220000000000>, actual: <c37e1e1436cfd62f89592c48211ffb6ad2f1dff0f69d2203072f1e6c3872a5919b42220000000000>
正如您现在所看到的,APK 签名被视为无效。我不知道为什么v3签名首先失败,可能是签名没有按v1,v2,v3的顺序验证...... 根据我的理解,除了 v1 之外的所有签名都应该在修改后的 APK 文件上失败。