我正在尝试解决此问题运行时应用程序签名验证不正确。对于我的 flutter 应用程序。
这个问题的描述是
Android 应用程序经过数字签名。在这种情况下,数字签名是一种加密构造,开发人员将其应用于软件以证明他/她编写了该软件。如果攻击者修改了应用程序中的某些内容并使用自己的签名重新签名,则该应用程序应该无法运行。应用程序应在运行时检查应用程序的当前签名与开发人员的签名。
所以我在我的应用程序中实现了以下代码
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:package_info_plus/package_info_plus.dart';
Future<void> verifyAppSignature() async {
if (kDebugMode) {
print('Skipping signature verification in debug mode.');
return;
}
if (kReleaseMode) {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String appSignature = await getPackageSignature(packageInfo.packageName);
String developerSignature = 'my_sha-1_key';
if (appSignature != developerSignature) {
print("appSign: $appSignature");
// SystemNavigator.pop();
// throw Exception('Release signature verification failed');
}
}
}
Future<String> getPackageSignature(String packageName) async {
try {
const MethodChannel channel = MethodChannel('app-release');
final String signature = await channel.invokeMethod('getSignature');
return signature;
} on PlatformException catch (e) {
return e.toString();
}
}
更改为
MainActivity.kt
package com.example.appname
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Build
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
private val CHANNEL = "app-release"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "getSignature") {
val signature = getSignature()
result.success(signature)
} else {
result.notImplemented()
}
}
}
private fun getSignature(): String {
return try {
val packageInfo: PackageInfo = packageManager.getPackageInfo(
packageName,
PackageManager.GET_SIGNATURES
)
val signature = packageInfo.signatures?.getOrNull(0)
signature?.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.toCharsString()
} else {
it.toString()
}
} ?: ""
} catch (e: Exception) {
e.printStackTrace()
""
}
}
}
但是这里的问题是
appSignature
是 X.509 certificate
键,而我的 developerSignature
是 sha-1
键。
如果有一种方法可以在
appSignature
函数中获取 sha-1
的 getPackageSignature
格式,或者将此 X.509 certificate
转换为 SHA-1
格式,那么这将是一个很大的帮助。
我已经弄清楚了。
在
MainActivity.kt
内部,我将这个 X.509 Certificate
格式转换为 SHA-1
格式。
进口
import java.io.ByteArrayInputStream
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
然后里面
getSignature()
signature?.let {
val certFactory = CertificateFactory.getInstance("X.509")
val x509Certificate = certFactory.generateCertificate(ByteArrayInputStream(it.toByteArray())) as X509Certificate
val sha1Bytes = x509Certificate.encoded.sha1()
// Convert the byte array to a hex string
sha1Bytes.joinToString("") { "%02x".format(it) }
} ?: ""
计算 SHA-1 哈希值的扩展函数
private fun ByteArray.sha1(): ByteArray {
val digest = java.security.MessageDigest.getInstance("SHA-1")
return digest.digest(this)
}
如果需要,您可以将“SHA-1”替换为“SHA-256”或其他算法