feat: 新增安全设备 Demo 及 Android 端 TEE 加解密模块

This commit is contained in:
2026-08-20 16:11:53 +08:00
commit bb33f3b5ae
31 changed files with 2803 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
package com.secure.demo;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.secure.device.DeviceCrypto;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* 最精简演示:在 KeyStore(TEE) 中生成 RSA-2048 密钥对,
* 完成「信封加密 → 解密还原」与「元数据签名 → 公钥验签」全流程,
* 无需任何后端即可在真机/模拟器上验证 DeviceCrypto 可用。
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.log);
new Thread(() -> {
StringBuilder sb = new StringBuilder();
try {
DeviceCrypto crypto = new DeviceCrypto(this);
String pub = crypto.getPublicKeyBase64();
sb.append("设备公钥(前48字符):\n").append(pub, 0, Math.min(48, pub.length()))
.append("...\n\n");
// 1) 信封加密(模拟拍照)
String plaintext = "私密照片数据 Hello TEE!";
DeviceCrypto.EncryptedPayload p = crypto.encryptData(plaintext.getBytes("UTF-8"));
sb.append("原始数据: ").append(plaintext).append("\n");
sb.append("密文: ").append(p.ciphertextBase64, 0, Math.min(32, p.ciphertextBase64.length()))
.append("...\n");
sb.append("IV: ").append(p.ivBase64).append("\n");
sb.append("DEK(明文, 实际应仅经HTTPS给服务端): ")
.append(p.dekBase64, 0, Math.min(24, p.dekBase64.length())).append("...\n\n");
// 2) 服务端用 UK 加密 DEK 后下发,此处用相同 DEK 还原,验证解密链路
byte[] dekBytes = Base64.getDecoder().decode(p.dekBase64);
byte[] decrypted = crypto.decryptPhoto(p.ciphertextBase64, p.ivBase64, dekBytes);
sb.append("解密还原: ").append(new String(decrypted, "UTF-8")).append("\n\n");
// 3) 元数据签名 + 公钥验签
String metadata = crypto.getDeviceSN() + "|" + System.currentTimeMillis() + "|photo001";
String sig = crypto.signMetadata(metadata);
sb.append("元数据: ").append(metadata).append("\n");
sb.append("签名(前32字符): ").append(sig, 0, Math.min(32, sig.length())).append("...\n");
boolean ok = verify(metadata, sig, pub);
sb.append("验签结果: ").append(ok ? "通过 ✅" : "失败 ❌").append("\n");
} catch (Exception e) {
sb.append("异常: ").append(e).append("\n");
e.printStackTrace();
}
final String text = sb.toString();
runOnUiThread(() -> tv.setText(text));
}).start();
}
private boolean verify(String metadata, String sigBase64, String pubKeyBase64) throws Exception {
java.security.PublicKey pub = KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(pubKeyBase64)));
Signature s = Signature.getInstance("SHA256withRSA");
s.initVerify(pub);
s.update(metadata.getBytes("UTF-8"));
return s.verify(Base64.getDecoder().decode(sigBase64));
}
}