Skip to content

Commit

Permalink
1、签名适配低版本
Browse files Browse the repository at this point in the history
  • Loading branch information
venson1992 committed Feb 15, 2022
1 parent 6fde93a commit 914ea12
Show file tree
Hide file tree
Showing 15 changed files with 159 additions and 45 deletions.
9 changes: 9 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ plugins {
}

android {
//加载资源
Properties properties = new Properties()
InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream()
properties.load(inputStream)
//读取字段
def keyAlias = properties.getProperty('keyAlias')
def keyPassword = properties.getProperty('keyPassword')
compileSdkVersion COMPILE_SDK_VERSION as int
buildToolsVersion BUILD_TOOLS_VERSION
defaultConfig {
Expand All @@ -14,6 +21,8 @@ android {
versionName BUILD_VERSION
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
buildConfigField("String", "ks_alias", '"' + keyAlias + '"')
buildConfigField("String", "ks_password", '"' + keyPassword + '"')
}
buildTypes {
release {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.venson.apk.signer

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand Down
7 changes: 5 additions & 2 deletions app/src/main/java/com/venson/apk/signer/SignActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class SignActivity : AppCompatActivity() {
startActivity(intent)
}
}
mPasswordEditView.setText(BuildConfig.ks_password)
mAliasEditView.setText(BuildConfig.ks_alias)
mSignButton.setOnClickListener {
clickAction()
}
Expand All @@ -66,7 +68,8 @@ class SignActivity : AppCompatActivity() {

private fun getTestApk(): File {
// val srcFilePath = "/storage/emulated/0/25game/apps/-1702942688.apk"
val srcFilePath = "/storage/emulated/0/25game/apps/-2034501281.apk"
// val srcFilePath = "/storage/emulated/0/25game/apps/-2034501281.apk"
val srcFilePath = "/storage/sdcard/25game/apps/-823954455.apk"
val srcFile = File(srcFilePath)
printLog("srcFile=$srcFile")
return srcFile
Expand Down Expand Up @@ -112,7 +115,7 @@ class SignActivity : AppCompatActivity() {
val signAlias = mAliasEditView.text.toString()
try {
sign(srcFile, signedApk, signFile, signPassword, signAlias)
printLog("signed successful! ${signFile.absolutePath}", true)
printLog("signed successful! ${signedApk.absolutePath}", true)
} catch (e: Exception) {
printLog(e, true)
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-night/themes.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<resources>
<!-- Base application theme. -->
<style name="Base.Theme.ApkSignerForAndroid" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your dark theme here. -->
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-v29/themes.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<resources>

<style name="Theme.ApkSignerForAndroid" parent="Base.Theme.ApkSignerForAndroid">
<!-- Transparent system bars for edge-to-edge. -->
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<resources>
<!-- Base application theme. -->
<style name="Base.Theme.ApkSignerForAndroid" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your light theme here. -->
Expand Down
3 changes: 1 addition & 2 deletions app/src/test/java/com/venson/apk/signer/ExampleUnitTest.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.venson.apk.signer

import org.junit.Assert.assertEquals
import org.junit.Test

import org.junit.Assert.*

/**
* Example local unit test, which will execute on the development machine (host).
*
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ kotlin.code.style=official
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
GROUP=com.github.venson1992
BUILD_VERSION=0.0.2
BUILD_VERSION_INT=2
BUILD_VERSION=0.0.3
BUILD_VERSION_INT=3
BUILD_TOOLS_VERSION=30.0.3
COMPILE_SDK_VERSION=31
MIN_SDK_VERSION=17
Expand Down
3 changes: 1 addition & 2 deletions lib_apk_signer/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.apksigner">
<manifest package="com.android.apksigner">

<application>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;

import javax.security.auth.x500.X500Principal;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.android.apksig.internal.apk;

/**
* @author Windysha
*/
public interface Supplier<T> {

/**
* Gets a result.
*
* @return a result
*/
T get();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getSignerInfoDigestAlgorithmOid;
import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getSignerInfoSignatureAlgorithm;

import android.util.Base64;

import com.android.apksig.apk.ApkFormatException;
import com.android.apksig.internal.apk.ApkSigningBlockUtils;
import com.android.apksig.internal.asn1.Asn1EncodingException;
Expand All @@ -41,7 +43,6 @@
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -373,7 +374,7 @@ public static OutputManifestFile generateManifestFile(
Attributes entryAttrs = new Attributes();
entryAttrs.putValue(
entryDigestAttributeName,
Base64.getEncoder().encodeToString(entryDigest));
Base64.encodeToString(entryDigest, Base64.DEFAULT));
ByteArrayOutputStream sectionOut = new ByteArrayOutputStream();
byte[] sectionBytes;
try {
Expand Down Expand Up @@ -435,7 +436,7 @@ private static byte[] generateSignatureFile(
if (attrValue.length() > 0) {
attrValue.append(", ");
}
attrValue.append(String.valueOf(id));
attrValue.append(id);
}
mainAttrs.put(
SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME,
Expand All @@ -446,7 +447,7 @@ private static byte[] generateSignatureFile(
MessageDigest md = getMessageDigestInstance(manifestDigestAlgorithm);
mainAttrs.putValue(
getManifestDigestAttributeName(manifestDigestAlgorithm),
Base64.getEncoder().encodeToString(md.digest(manifest.contents)));
Base64.encodeToString(md.digest(manifest.contents), Base64.DEFAULT));
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
SignatureFileWriter.writeMainSection(out, mainAttrs);
Expand All @@ -462,8 +463,8 @@ private static byte[] generateSignatureFile(
Attributes attrs = new Attributes();
attrs.putValue(
entryDigestAttributeName,
Base64.getEncoder().encodeToString(sectionDigest));

Base64.encodeToString(sectionDigest, Base64.DEFAULT)
);
try {
SignatureFileWriter.writeIndividualSection(out, sectionName, attrs);
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.android.apksig.internal.asn1;

import android.os.Build;

import com.android.apksig.internal.asn1.ber.BerDataValue;
import com.android.apksig.internal.asn1.ber.BerDataValueFormatException;
import com.android.apksig.internal.asn1.ber.BerDataValueReader;
Expand Down Expand Up @@ -173,7 +175,15 @@ private static <T> T parseChoice(BerDataValue dataValue, Class<T> containerClass
T obj;
try {
obj = containerClass.getConstructor().newInstance();
} catch (IllegalArgumentException | ReflectiveOperationException e) {
} catch (Exception e) {
if (e instanceof IllegalArgumentException) {
throw new Asn1DecodingException("Failed to instantiate " + containerClass.getName(), e);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (e instanceof ReflectiveOperationException) {
throw new Asn1DecodingException("Failed to instantiate " + containerClass.getName(), e);
}
}
throw new Asn1DecodingException("Failed to instantiate " + containerClass.getName(), e);
}
// Set the matching field's value from the data value
Expand Down Expand Up @@ -219,7 +229,14 @@ private static <T> T parseSequence(BerDataValue container, Class<T> containerCla
T t;
try {
t = containerClass.getConstructor().newInstance();
} catch (IllegalArgumentException | ReflectiveOperationException e) {
} catch (IllegalArgumentException e) {
throw new Asn1DecodingException("Failed to instantiate " + containerClass.getName(), e);
} catch (Exception e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (e instanceof ReflectiveOperationException) {
throw new Asn1DecodingException("Failed to instantiate " + containerClass.getName(), e);
}
}
throw new Asn1DecodingException("Failed to instantiate " + containerClass.getName(), e);
}

Expand Down Expand Up @@ -309,7 +326,12 @@ private static <T> List<T> parseSetOf(BerDataValue container, Class<T> elementCl

private static Asn1Type getContainerAsn1Type(Class<?> containerClass)
throws Asn1DecodingException {
Asn1Class containerAnnotation = containerClass.getDeclaredAnnotation(Asn1Class.class);
Asn1Class containerAnnotation;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
containerAnnotation = containerClass.getDeclaredAnnotation(Asn1Class.class);
} else {
containerAnnotation = containerClass.getAnnotation(Asn1Class.class);
}
if (containerAnnotation == null) {
throw new Asn1DecodingException(
containerClass.getName() + " is not annotated with "
Expand All @@ -330,7 +352,12 @@ private static Asn1Type getContainerAsn1Type(Class<?> containerClass)

private static Class<?> getElementType(Field field)
throws Asn1DecodingException, ClassNotFoundException {
String type = field.getGenericType().getTypeName();
String type;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
type = field.getGenericType().getTypeName();
} else {
type = field.getGenericType().toString();
}
int delimiterIndex = type.indexOf('<');
if (delimiterIndex == -1) {
throw new Asn1DecodingException("Not a container type: " + field.getGenericType());
Expand Down Expand Up @@ -506,7 +533,11 @@ private static BigInteger integerToBigInteger(ByteBuffer encoded) {
private static int integerToInt(ByteBuffer encoded) throws Asn1DecodingException {
BigInteger value = integerToBigInteger(encoded);
try {
return value.intValueExact();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
return value.intValueExact();
} else {
return value.intValue();
}
} catch (ArithmeticException e) {
throw new Asn1DecodingException(
String.format("INTEGER cannot be represented as int: %1$d (0x%1$x)", value), e);
Expand All @@ -516,7 +547,11 @@ private static int integerToInt(ByteBuffer encoded) throws Asn1DecodingException
private static long integerToLong(ByteBuffer encoded) throws Asn1DecodingException {
BigInteger value = integerToBigInteger(encoded);
try {
return value.longValueExact();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
return value.longValueExact();
} else {
return value.longValue();
}
} catch (ArithmeticException e) {
throw new Asn1DecodingException(
String.format("INTEGER cannot be represented as long: %1$d (0x%1$x)", value),
Expand All @@ -529,7 +564,12 @@ private static List<AnnotatedField> getAnnotatedFields(Class<?> containerClass)
Field[] declaredFields = containerClass.getDeclaredFields();
List<AnnotatedField> result = new ArrayList<>(declaredFields.length);
for (Field field : declaredFields) {
Asn1Field annotation = field.getDeclaredAnnotation(Asn1Field.class);
Asn1Field annotation;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
annotation = field.getDeclaredAnnotation(Asn1Field.class);
} else {
annotation = field.getAnnotation(Asn1Field.class);
}
if (annotation == null) {
continue;
}
Expand Down Expand Up @@ -574,7 +614,15 @@ public static void setFieldValue(
field.set(obj, convert(type, dataValue, field.getType()));
break;
}
} catch (ReflectiveOperationException e) {
} catch (Exception e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (e instanceof ReflectiveOperationException) {
throw new Asn1DecodingException(
"Failed to set value of " + obj.getClass().getName()
+ "." + field.getName(),
e);
}
}
throw new Asn1DecodingException(
"Failed to set value of " + obj.getClass().getName()
+ "." + field.getName(),
Expand Down Expand Up @@ -643,17 +691,25 @@ public static <T> T convert(
}
break;
case SEQUENCE: {
Asn1Class containerAnnotation =
targetType.getDeclaredAnnotation(Asn1Class.class);
Asn1Class containerAnnotation;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
containerAnnotation = targetType.getDeclaredAnnotation(Asn1Class.class);
} else {
containerAnnotation = targetType.getAnnotation(Asn1Class.class);
}
if ((containerAnnotation != null)
&& (containerAnnotation.type() == Asn1Type.SEQUENCE)) {
return parseSequence(dataValue, targetType);
}
break;
}
case CHOICE: {
Asn1Class containerAnnotation =
targetType.getDeclaredAnnotation(Asn1Class.class);
Asn1Class containerAnnotation;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
containerAnnotation = targetType.getDeclaredAnnotation(Asn1Class.class);
} else {
containerAnnotation = targetType.getAnnotation(Asn1Class.class);
}
if ((containerAnnotation != null)
&& (containerAnnotation.type() == Asn1Type.CHOICE)) {
return parseChoice(dataValue, targetType);
Expand Down
Loading

0 comments on commit 914ea12

Please sign in to comment.