-
Notifications
You must be signed in to change notification settings - Fork 833
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #286 from luckyloogn/feat-add-signature-and-permis…
…sion-configuration 新增打包签名配置、签名密钥管理、打包权限设置
- Loading branch information
Showing
40 changed files
with
2,978 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
app/src/main/java/org/autojs/autojs/apkbuilder/keystore/AESUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package org.autojs.autojs.apkbuilder.keystore | ||
|
||
import android.util.Base64 | ||
import javax.crypto.Cipher | ||
import javax.crypto.SecretKey | ||
import javax.crypto.spec.GCMParameterSpec | ||
import android.security.keystore.KeyGenParameterSpec | ||
import android.security.keystore.KeyProperties | ||
import java.security.KeyStore | ||
import javax.crypto.KeyGenerator | ||
|
||
object AESUtils { | ||
|
||
private const val TRANSFORMATION = "AES/GCM/NoPadding" | ||
private const val TAG_LENGTH = 128 | ||
|
||
private const val KEY_ALIAS = "autojs6_key_store_aes_key" | ||
|
||
private fun getKey(): SecretKey { | ||
val keyStore = KeyStore.getInstance("AndroidKeyStore") | ||
keyStore.load(null) | ||
|
||
val key = keyStore.getKey(KEY_ALIAS, null) | ||
if (key != null) { | ||
return key as SecretKey | ||
} | ||
|
||
val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore") | ||
val keyGenParameterSpec = KeyGenParameterSpec.Builder(KEY_ALIAS, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) | ||
.setBlockModes(KeyProperties.BLOCK_MODE_GCM) | ||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) | ||
.build() | ||
|
||
keyGenerator.init(keyGenParameterSpec) | ||
return keyGenerator.generateKey() | ||
} | ||
|
||
// 加密 | ||
fun encrypt(data: String): String { | ||
val secretKey: SecretKey = getKey() | ||
val cipher = Cipher.getInstance(TRANSFORMATION) | ||
|
||
cipher.init(Cipher.ENCRYPT_MODE, secretKey) | ||
|
||
val encryptedData = cipher.doFinal(data.toByteArray()) | ||
val encryptedBase64 = Base64.encodeToString(encryptedData, Base64.NO_WRAP) | ||
val ivBase64 = Base64.encodeToString(cipher.iv, Base64.NO_WRAP) | ||
|
||
return "$ivBase64:$encryptedBase64" | ||
} | ||
|
||
// 解密 | ||
fun decrypt(encryptedData: String): String { | ||
val parts = encryptedData.split(":") | ||
val ivBase64 = parts[0] | ||
val encryptedBase64 = parts[1] | ||
|
||
val iv = Base64.decode(ivBase64, Base64.NO_WRAP) | ||
val encrypted = Base64.decode(encryptedBase64, Base64.NO_WRAP) | ||
|
||
val secretKey: SecretKey = getKey() | ||
val cipher = Cipher.getInstance(TRANSFORMATION) | ||
|
||
val gcmSpec = GCMParameterSpec(TAG_LENGTH, iv) | ||
cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmSpec) | ||
|
||
val decryptedData = cipher.doFinal(encrypted) | ||
|
||
return String(decryptedData) | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
app/src/main/java/org/autojs/autojs/apkbuilder/keystore/KeyStore.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.autojs.autojs.apkbuilder.keystore | ||
|
||
import androidx.room.ColumnInfo | ||
import androidx.room.Entity | ||
import androidx.room.PrimaryKey | ||
|
||
|
||
@Entity | ||
data class KeyStore( | ||
@PrimaryKey val absolutePath: String, // 密钥库绝对路径 | ||
@ColumnInfo(name = "filename") val filename: String = "", // 文件名 | ||
@ColumnInfo(name = "password") val password: String = "", // 密码 | ||
@ColumnInfo(name = "alias") val alias: String = "", // 别名 | ||
@ColumnInfo(name = "alias_password") val aliasPassword: String = "", // 别名密码 | ||
@ColumnInfo(name = "verified") val verified: Boolean = false, // 验证状态 | ||
) { | ||
override fun toString(): String = filename | ||
} |
29 changes: 29 additions & 0 deletions
29
app/src/main/java/org/autojs/autojs/apkbuilder/keystore/KeyStoreDao.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package org.autojs.autojs.apkbuilder.keystore | ||
|
||
import androidx.room.Dao | ||
import androidx.room.Delete | ||
import androidx.room.Query | ||
import androidx.room.Upsert | ||
|
||
|
||
@Dao | ||
interface KeyStoreDao { | ||
|
||
@Query("SELECT * FROM keystore WHERE absolutePath = :absolutePath LIMIT 1") | ||
suspend fun getByAbsolutePath(absolutePath: String): KeyStore? | ||
|
||
@Upsert | ||
suspend fun upsert(vararg keyStores: KeyStore) | ||
|
||
@Query("SELECT * FROM keystore") | ||
suspend fun getAll(): List<KeyStore> | ||
|
||
@Delete | ||
suspend fun delete(vararg keyStores: KeyStore) | ||
|
||
@Query("DELETE FROM keystore WHERE absolutePath = :absolutePath") | ||
suspend fun deleteByAbsolutePath(absolutePath: String): Int | ||
|
||
@Query("DELETE FROM keystore") | ||
suspend fun deleteAll() | ||
} |
28 changes: 28 additions & 0 deletions
28
app/src/main/java/org/autojs/autojs/apkbuilder/keystore/KeyStoreDatabase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.autojs.autojs.apkbuilder.keystore | ||
|
||
import android.content.Context | ||
import androidx.room.Database | ||
import androidx.room.Room | ||
import androidx.room.RoomDatabase | ||
|
||
@Database(entities = [KeyStore::class], version = 1, exportSchema = false) | ||
abstract class KeyStoreDatabase : RoomDatabase() { | ||
abstract fun keyStoreDao(): KeyStoreDao | ||
|
||
companion object { | ||
@Volatile | ||
private var INSTANCE: KeyStoreDatabase? = null | ||
|
||
fun getDatabase(context: Context): KeyStoreDatabase { | ||
return INSTANCE ?: synchronized(this) { | ||
val instance = Room.databaseBuilder( | ||
context.applicationContext, | ||
KeyStoreDatabase::class.java, | ||
"keystore-database" | ||
).build() | ||
INSTANCE = instance | ||
instance | ||
} | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
app/src/main/java/org/autojs/autojs/apkbuilder/keystore/KeyStoreRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.autojs.autojs.apkbuilder.keystore | ||
|
||
import android.content.Context | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.withContext | ||
|
||
class KeyStoreRepository(context: Context) { | ||
|
||
private var dao: KeyStoreDao | ||
|
||
init { | ||
val keyStoreDatabase = KeyStoreDatabase.getDatabase(context) | ||
dao = keyStoreDatabase.keyStoreDao() | ||
} | ||
|
||
// 获取所有 KeyStore | ||
suspend fun getAllKeyStores(): List<KeyStore> { | ||
return withContext(Dispatchers.IO) { | ||
dao.getAll() | ||
} | ||
} | ||
|
||
// 插入或更新 KeyStore | ||
suspend fun upsertKeyStores(vararg keyStores: KeyStore) { | ||
withContext(Dispatchers.IO) { | ||
dao.upsert(*keyStores) | ||
} | ||
} | ||
|
||
// 根据绝对路径获取 KeyStore | ||
suspend fun getKeyStoreAbsolutePath(absolutePath: String): KeyStore? { | ||
return withContext(Dispatchers.IO) { | ||
dao.getByAbsolutePath(absolutePath) | ||
} | ||
} | ||
|
||
// 删除 KeyStore | ||
suspend fun deleteKeyStores(vararg keyStores: KeyStore) { | ||
withContext(Dispatchers.IO) { | ||
dao.delete(*keyStores) | ||
} | ||
} | ||
|
||
// 删除所有 KeyStore | ||
suspend fun deleteAllKeyStores() { | ||
withContext(Dispatchers.IO) { | ||
dao.deleteAll() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.