Skip to content

Commit 3300fb9

Browse files
committed
签名校验
1 parent 5985dc6 commit 3300fb9

File tree

6 files changed

+158
-0
lines changed

6 files changed

+158
-0
lines changed

app/build.gradle.kts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ android {
4949
buildTypes {
5050
debug {
5151
signingConfig = signingConfigs.getByName("cyrus")
52+
53+
// 注入期望签名指纹
54+
buildConfigField(
55+
"String",
56+
"EXPECTED_SIGNATURE",
57+
"\"4ODG9MBS1sIB91m3GO2PQB2VzhBAYl1xjMajotXMiRc=\""
58+
)
5259
}
5360
release {
5461
signingConfig = signingConfigs.getByName("cyrus")
@@ -57,6 +64,13 @@ android {
5764
getDefaultProguardFile("proguard-android-optimize.txt"),
5865
"proguard-rules.pro"
5966
)
67+
68+
// 注入期望签名指纹
69+
buildConfigField(
70+
"String",
71+
"EXPECTED_SIGNATURE",
72+
"\"4ODG9MBS1sIB91m3GO2PQB2VzhBAYl1xjMajotXMiRc=\""
73+
)
6074
}
6175
}
6276
compileOptions {
@@ -69,6 +83,7 @@ android {
6983
buildFeatures {
7084
compose = true
7185
prefab = true
86+
buildConfig = true
7287
}
7388
ndkVersion = "27.1.12297006"
7489
}

app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
android:theme="@style/Theme.AndroidExample"
2020
tools:ignore="HardcodedDebugMode"
2121
tools:targetApi="31">
22+
<activity
23+
android:name=".signature.SignatureActivity"
24+
android:exported="false"
25+
android:theme="@style/Theme.AndroidExample" />
2226
<activity
2327
android:name=".sohooker.SoHookerActivity"
2428
android:exported="false"

app/src/main/java/com/cyrus/example/MainActivity.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import com.cyrus.example.unicorn.UnicornActivity
3333
import com.cyrus.example.unidbg.UnidbgActivity
3434
import com.cyrus.example.vmp.VMPActivity
3535
import com.cyrus.example.retrofit.RetrofitActivity
36+
import com.cyrus.example.signature.SignatureActivity
3637
import com.cyrus.example.sohooker.SoHookerActivity
3738

3839

@@ -297,5 +298,15 @@ class MainActivity : AppCompatActivity() {
297298
)
298299
startActivity(intent)
299300
}
301+
302+
303+
// 签名校验
304+
findViewById<Button>(R.id.button_check_signature).setOnClickListener {
305+
val intent = Intent(
306+
this@MainActivity,
307+
SignatureActivity::class.java
308+
)
309+
startActivity(intent)
310+
}
300311
}
301312
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.cyrus.example.signature
2+
3+
import android.os.Bundle
4+
import androidx.activity.ComponentActivity
5+
import androidx.activity.compose.setContent
6+
import androidx.compose.foundation.layout.*
7+
import androidx.compose.material3.*
8+
import androidx.compose.runtime.*
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.graphics.Color
11+
import androidx.compose.ui.unit.dp
12+
import androidx.compose.ui.platform.LocalContext
13+
import com.cyrus.example.BuildConfig
14+
15+
16+
class SignatureActivity : ComponentActivity() {
17+
override fun onCreate(savedInstanceState: Bundle?) {
18+
super.onCreate(savedInstanceState)
19+
setContent {
20+
SignatureScreen()
21+
}
22+
}
23+
}
24+
25+
@Composable
26+
fun SignatureScreen() {
27+
val context = LocalContext.current
28+
var output by remember { mutableStateOf("日志输出区\n") }
29+
30+
Column(
31+
modifier = Modifier
32+
.fillMaxSize()
33+
.padding(16.dp),
34+
verticalArrangement = Arrangement.spacedBy(12.dp)
35+
) {
36+
Button(
37+
onClick = {
38+
val sigs = SignatureUtils.getSigningSha256Base64(context)
39+
output = "当前签名指纹:\n" + sigs.joinToString("\n")
40+
},
41+
modifier = Modifier.fillMaxWidth()
42+
) {
43+
Text("打印当前 App 签名指纹")
44+
}
45+
46+
Button(
47+
onClick = {
48+
val expected = BuildConfig.EXPECTED_SIGNATURE
49+
val ok = SignatureUtils.isSignedWith(context, expected)
50+
output = "签名校验结果: $ok\n\n期望签名: $expected"
51+
},
52+
modifier = Modifier.fillMaxWidth()
53+
) {
54+
Text("执行签名校验")
55+
}
56+
57+
Spacer(modifier = Modifier.height(16.dp))
58+
59+
Text(
60+
text = output,
61+
color = Color.White,
62+
modifier = Modifier
63+
.fillMaxWidth()
64+
.weight(1f)
65+
)
66+
}
67+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// SignatureUtils.kt
2+
package com.cyrus.example.signature
3+
4+
import android.content.Context
5+
import android.content.pm.PackageManager
6+
import android.os.Build
7+
import android.util.Base64
8+
import android.util.Log
9+
import java.security.MessageDigest
10+
11+
object SignatureUtils {
12+
private const val TAG = "SignatureUtils"
13+
14+
/** 返回当前 app 的签名指纹列表(Base64(SHA256(certBytes))) */
15+
fun getSigningSha256Base64(context: Context): List<String> {
16+
val res = mutableListOf<String>()
17+
try {
18+
val pm = context.packageManager
19+
val pkg = context.packageName
20+
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
21+
pm.getPackageInfo(pkg, PackageManager.GET_SIGNING_CERTIFICATES)
22+
} else {
23+
@Suppress("DEPRECATION")
24+
pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES)
25+
}
26+
27+
val signatures = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
28+
packageInfo.signingInfo.apkContentsSigners
29+
} else {
30+
@Suppress("DEPRECATION")
31+
packageInfo.signatures
32+
}
33+
34+
for (sig in signatures) {
35+
val certBytes = sig.toByteArray()
36+
val md = MessageDigest.getInstance("SHA-256")
37+
val digest = md.digest(certBytes)
38+
val base64 = Base64.encodeToString(digest, Base64.NO_WRAP)
39+
Log.d(TAG, "Runtime sign sha256 base64: $base64")
40+
res.add(base64)
41+
}
42+
} catch (e: Exception) {
43+
Log.e(TAG, "getSigningSha256Base64 error", e)
44+
}
45+
return res
46+
}
47+
48+
/** 检查任一签名是否与期望值相等 */
49+
fun isSignedWith(context: Context, expectedBase64: String): Boolean {
50+
val list = getSigningSha256Base64(context)
51+
for (s in list) if (s == expectedBase64) return true
52+
return false
53+
}
54+
}

app/src/main/res/layout/activity_main.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,13 @@
214214
android:layout_marginTop="12dp"
215215
android:text="动态篡改 so 函数返回值" />
216216

217+
<Button
218+
android:id="@+id/button_check_signature"
219+
android:layout_width="wrap_content"
220+
android:layout_height="wrap_content"
221+
android:layout_marginTop="12dp"
222+
android:text="签名校验" />
223+
217224
</LinearLayout>
218225

219226
</ScrollView>

0 commit comments

Comments
 (0)