Skip to content

Commit 00229e8

Browse files
committed
指令流加密
1 parent 473434b commit 00229e8

File tree

9 files changed

+247
-0
lines changed

9 files changed

+247
-0
lines changed

app/src/main/assets/sign.key

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
��\���`���ߖ

app/src/main/assets/sign.vmp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
�t����8��9E���Ę�X6 �UJ�Ʌ�ɚ
2+
K�I��o!]�4�l�Ndaz�*��G�
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.cyrus.example.vmp
2+
3+
import android.content.Context
4+
import java.io.InputStream
5+
import javax.crypto.Cipher
6+
import javax.crypto.SecretKey
7+
import javax.crypto.spec.SecretKeySpec
8+
9+
object AESUtils {
10+
private const val ALGORITHM = "AES"
11+
private const val TRANSFORMATION = "AES/ECB/PKCS5Padding"
12+
13+
// 从 assets 中读取文件并解密
14+
fun decryptFileFromAssets(context: Context, vmpFileName: String, keyFileName: String): ByteArray? {
15+
// 读取密钥文件
16+
val key = loadKeyFromAssets(context, keyFileName)
17+
18+
// 读取加密的 vmp 文件
19+
val encryptedData = readFileFromAssets(context, vmpFileName)
20+
21+
// 解密
22+
return decrypt(encryptedData, key)
23+
}
24+
25+
// 读取文件内容为字节数组
26+
private fun readFileFromAssets(context: Context, fileName: String): ByteArray {
27+
val inputStream: InputStream = context.assets.open(fileName)
28+
return inputStream.readBytes()
29+
}
30+
31+
// 从 assets 中加载密钥文件
32+
private fun loadKeyFromAssets(context: Context, keyFileName: String): SecretKey {
33+
val keyBytes = readFileFromAssets(context, keyFileName)
34+
return SecretKeySpec(keyBytes, ALGORITHM)
35+
}
36+
37+
// 解密
38+
private fun decrypt(data: ByteArray, key: SecretKey): ByteArray {
39+
val cipher = Cipher.getInstance(TRANSFORMATION)
40+
cipher.init(Cipher.DECRYPT_MODE, key)
41+
return cipher.doFinal(data)
42+
}
43+
}

app/src/main/java/com/cyrus/example/vmp/VMPActivity.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ class VMPActivity : AppCompatActivity() {
5050
Toast.makeText(this, result, Toast.LENGTH_SHORT).show()
5151
}
5252

53+
// Sign算法(指令流加密 VMP)
54+
findViewById<Button>(R.id.button_sign_vmp_encrypted).setOnClickListener {
55+
// 解密并执行指令流
56+
val bytecode = readInstructionFromAssets()
57+
58+
// 通过 VMP 解析器执行指令流
59+
if (bytecode != null) {
60+
61+
val result = SimpleVMP.execute(bytecode, input)
62+
63+
// 显示 Toast
64+
Toast.makeText(this, result, Toast.LENGTH_SHORT).show()
65+
}
66+
}
67+
5368
// const-string 指令
5469
findViewById<Button>(R.id.button_const_string).setOnClickListener {
5570
// 模拟字节码输入
@@ -128,4 +143,14 @@ class VMPActivity : AppCompatActivity() {
128143

129144
}
130145

146+
private fun readInstructionFromAssets(): ByteArray? {
147+
// 文件名:在 assets 中放置的加密文件和密钥文件
148+
val vmpFileName = "sign.vmp"
149+
val keyFileName = "sign.key"
150+
151+
// 解密文件
152+
val decryptedData = AESUtils.decryptFileFromAssets(this, vmpFileName, keyFileName)
153+
return decryptedData
154+
}
155+
131156
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131
android:layout_marginTop="12dp"
3232
android:text="Sign算法(VMP)" />
3333

34+
<Button
35+
android:id="@+id/button_sign_vmp_encrypted"
36+
android:layout_width="wrap_content"
37+
android:layout_height="wrap_content"
38+
android:layout_marginTop="12dp"
39+
android:text="Sign算法(指令流加密 VMP)" />
40+
3441
<Button
3542
android:id="@+id/button_const_string"
3643
android:layout_width="wrap_content"

vmp/sign/sign

60 Bytes
Binary file not shown.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.cyrus.vmp
2+
3+
import java.io.ByteArrayOutputStream
4+
import java.io.File
5+
import java.io.FileInputStream
6+
import java.io.FileOutputStream
7+
import javax.crypto.Cipher
8+
import javax.crypto.KeyGenerator
9+
import javax.crypto.SecretKey
10+
import javax.crypto.spec.SecretKeySpec
11+
12+
object AESUtils {
13+
14+
private const val ALGORITHM = "AES"
15+
private const val TRANSFORMATION = "AES/ECB/PKCS5Padding" // AES 加密模式
16+
17+
// 生成一个 128 位的 AES 密钥
18+
fun generateSecretKey(): SecretKey {
19+
val keyGenerator = KeyGenerator.getInstance(ALGORITHM)
20+
keyGenerator.init(128) // AES 128 位
21+
return keyGenerator.generateKey()
22+
}
23+
24+
// 使用给定的密钥加密数据
25+
fun encrypt(data: ByteArray, key: SecretKey): ByteArray {
26+
val cipher = Cipher.getInstance(TRANSFORMATION)
27+
cipher.init(Cipher.ENCRYPT_MODE, key)
28+
return cipher.doFinal(data)
29+
}
30+
31+
// 使用给定的密钥解密数据
32+
fun decrypt(data: ByteArray, key: SecretKey): ByteArray {
33+
val cipher = Cipher.getInstance(TRANSFORMATION)
34+
cipher.init(Cipher.DECRYPT_MODE, key)
35+
return cipher.doFinal(data)
36+
}
37+
38+
// 将文件内容加密并导出到新文件
39+
fun encryptFile(inputFile: File, outputFile: File, keyFile: File) {
40+
// 读取文件内容
41+
val fileData = readFile(inputFile)
42+
43+
// 生成密钥
44+
val secretKey = generateSecretKey()
45+
46+
// 加密文件内容
47+
val encryptedData = encrypt(fileData, secretKey)
48+
49+
// 保存加密后的数据到新文件(.vmp 文件)
50+
writeFile(outputFile, encryptedData)
51+
52+
// 保存密钥到文件
53+
saveKeyToFile(secretKey, keyFile)
54+
}
55+
56+
// 解密文件内容并导出到新文件
57+
fun decryptFile(inputFile: File, outputFile: File, keyFile: File) {
58+
// 从文件加载密钥
59+
val secretKey = loadKeyFromFile(keyFile)
60+
61+
// 读取加密后的文件内容
62+
val encryptedData = readFile(inputFile)
63+
64+
// 解密文件内容
65+
val decryptedData = decrypt(encryptedData, secretKey)
66+
67+
// 保存解密后的数据到文件
68+
writeFile(outputFile, decryptedData)
69+
}
70+
71+
// 读取文件内容并返回字节数组
72+
fun readFile(file: File): ByteArray {
73+
val fis = FileInputStream(file)
74+
val baos = ByteArrayOutputStream()
75+
val buffer = ByteArray(1024)
76+
var bytesRead: Int
77+
while (fis.read(buffer).also { bytesRead = it } != -1) {
78+
baos.write(buffer, 0, bytesRead)
79+
}
80+
fis.close()
81+
return baos.toByteArray()
82+
}
83+
84+
// 将字节数组写入到文件
85+
fun writeFile(file: File, data: ByteArray) {
86+
val fos = FileOutputStream(file)
87+
fos.write(data)
88+
fos.close()
89+
}
90+
91+
// 保存密钥到文件
92+
private fun saveKeyToFile(key: SecretKey, keyFile: File) {
93+
val fos = FileOutputStream(keyFile)
94+
fos.write(key.encoded)
95+
fos.close()
96+
}
97+
98+
// 从文件加载密钥
99+
fun loadKeyFromFile(keyFile: File): SecretKey {
100+
val keyBytes = ByteArray(keyFile.length().toInt())
101+
val fis = FileInputStream(keyFile)
102+
fis.read(keyBytes)
103+
fis.close()
104+
return SecretKeySpec(keyBytes, ALGORITHM)
105+
}
106+
107+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.cyrus.vmp
2+
3+
import com.cyrus.vmp.AESUtils.loadKeyFromFile
4+
import com.cyrus.vmp.AESUtils.readFile
5+
import com.cyrus.vmp.AESUtils.writeFile
6+
import java.io.File
7+
8+
9+
fun main() {
10+
11+
// 获取工程根目录路径
12+
val projectRoot = System.getProperty("user.dir")
13+
14+
// 输入加密文件路径
15+
val encryptedFile = File(projectRoot, "vmp/sign/sign.vmp")
16+
17+
// 密钥文件路径
18+
val keyFile = File(projectRoot, "vmp/sign/sign.key")
19+
20+
// 输出解密文件路径
21+
val decryptedFile = File(projectRoot, "vmp/sign/sign_")
22+
23+
try {
24+
// 从文件加载密钥
25+
val secretKey = loadKeyFromFile(keyFile)
26+
27+
// 解密文件
28+
val encryptedData = readFile(encryptedFile)
29+
val decryptedData: ByteArray = AESUtils.decrypt(encryptedData, secretKey)
30+
31+
// 保存解密后的文件
32+
writeFile(decryptedFile, decryptedData)
33+
println("File decryption completed, saved as: ${decryptedFile.absolutePath}")
34+
} catch (e: Exception) {
35+
e.printStackTrace()
36+
}
37+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.cyrus.vmp
2+
3+
import java.io.File
4+
5+
fun main() {
6+
// 获取工程根目录路径
7+
val projectRoot = System.getProperty("user.dir")
8+
9+
// 设置相对路径
10+
val encryptedFile = File(projectRoot, "vmp/sign/sign.vmp") // 相对路径
11+
val keyFile = File(projectRoot, "vmp/sign/sign.key") // 相对路径
12+
13+
// 输入文件路径
14+
val inputFile = File(projectRoot, "vmp/sign/sign") // 需要加密的文件
15+
16+
17+
try {
18+
// 使用 AES 加密文件
19+
AESUtils.encryptFile(inputFile, encryptedFile, keyFile)
20+
println("File encryption completed, saved as: ${encryptedFile.absolutePath}")
21+
println("Key saved as: ${keyFile.absolutePath}")
22+
} catch (e: Exception) {
23+
e.printStackTrace()
24+
}
25+
}

0 commit comments

Comments
 (0)