临时存储

This commit is contained in:
zcy
2025-09-08 15:35:28 +08:00
parent 98d411d70d
commit b41fff9d09
3 changed files with 61 additions and 56 deletions

View File

@@ -6,6 +6,7 @@ import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
/**
* 仅做一次“自检调用”:
* 1) ctx.init(KEY, IV); Enc(Input) == EncExpected ?
@@ -13,65 +14,66 @@ import javacard.framework.Util;
* Response: 2字节 [encMatch, dblEncRestored]1=真0=假
*/
public final class Method {
// ======= 已按你提供的数据填充 =======
// ======= 请用你的向量替换下面占位内容 =======
// Key: 32字节
private static final byte[] KEY32 = new byte[] {
// TODO: 替换成你的32字节Key
(byte)0x00,(byte)0x01,(byte)0x02,(byte)0x03,(byte)0x04,(byte)0x05,(byte)0x06,(byte)0x07,
(byte)0x08,(byte)0x09,(byte)0x0A,(byte)0x0B,(byte)0x0C,(byte)0x0D,(byte)0x0E,(byte)0x0F,
(byte)0x10,(byte)0x11,(byte)0x12,(byte)0x13,(byte)0x14,(byte)0x15,(byte)0x16,(byte)0x17,
(byte)0x18,(byte)0x19,(byte)0x1A,(byte)0x1B,(byte)0x1C,(byte)0x1D,(byte)0x1E,(byte)0x1F
(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66
};
// IV: 25字节ZUC-256
// IV: 你提供的是23字节如需25字节请补齐两字节
private static final byte[] IV25 = new byte[] {
// TODO: 替换成你的25字节IV
(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5,(byte)0xA6,(byte)0xA7,
(byte)0xA8,(byte)0xA9,(byte)0xAA,(byte)0xAB,(byte)0xAC,(byte)0xAD,(byte)0xAE,(byte)0xAF,
(byte)0xB0,(byte)0xB1,(byte)0xB2,(byte)0xB3,(byte)0xB4,(byte)0xB5,(byte)0xB6,(byte)0xB7,
(byte)0xB8
(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
(byte)0x67,(byte)0xC3,(byte)0x1C,(byte)0xB3,(byte)0xD3,(byte)0x5D,(byte)0xB7
};
// Input: 建议长度为 4 的倍数,便于不走 finish 的残字节路径
// Input: 明文38字节
private static final byte[] INPUT = new byte[] {
// TODO: 替换成你的明文示例32字节
(byte)0x11,(byte)0x22,(byte)0x33,(byte)0x44,(byte)0x55,(byte)0x66,(byte)0x77,(byte)0x88,
(byte)0x99,(byte)0xAA,(byte)0xBB,(byte)0xCC,(byte)0xDD,(byte)0xEE,(byte)0xFF,(byte)0x00,
(byte)0x10,(byte)0x20,(byte)0x30,(byte)0x40,(byte)0x50,(byte)0x60,(byte)0x70,(byte)0x80,
(byte)0x90,(byte)0xA0,(byte)0xB0,(byte)0xC0,(byte)0xD0,(byte)0xE0,(byte)0xF0,(byte)0x00
(byte)0x5A,(byte)0x55,(byte)0x43,(byte)0x32,(byte)0x35,(byte)0x36,(byte)0xE5,(byte)0xAF,
(byte)0xB9,(byte)0xE7,(byte)0xA7,(byte)0xB0,(byte)0xE5,(byte)0x8A,(byte)0xA0,(byte)0xE8,
(byte)0xA7,(byte)0xA3,(byte)0xE5,(byte)0xAF,(byte)0x86,(byte)0xE6,(byte)0xB5,(byte)0x8B,
(byte)0xE8,(byte)0xAF,(byte)0x95,(byte)0x3A,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,
(byte)0x35,(byte)0x36,(byte)0x37,(byte)0x38,(byte)0x39,(byte)0x30
};
// EncResult: 期望密文(与上面的 Input 配套
// EncResult: 期望密文(38字节
private static final byte[] ENC_EXPECTED = new byte[] {
// TODO: 替换成你“已知正确”的密文(示例随便填;不改会导致第一项校验=0
(byte)0x21,(byte)0x32,(byte)0x43,(byte)0x54,(byte)0x65,(byte)0x76,(byte)0x87,(byte)0x98,
(byte)0xA9,(byte)0xBA,(byte)0xCB,(byte)0xDC,(byte)0xED,(byte)0xFE,(byte)0x0F,(byte)0x1E,
(byte)0x2D,(byte)0x3C,(byte)0x4B,(byte)0x5A,(byte)0x69,(byte)0x78,(byte)0x87,(byte)0x96,
(byte)0xA5,(byte)0xB4,(byte)0xC3,(byte)0xD2,(byte)0xE1,(byte)0xF0,(byte)0x0F,(byte)0x00
(byte)0x6C,(byte)0xEE,(byte)0x3C,(byte)0xFA,(byte)0xDE,(byte)0xBB,(byte)0xCB,(byte)0xE5,
(byte)0x33,(byte)0x51,(byte)0x07,(byte)0x07,(byte)0x90,(byte)0x25,(byte)0x93,(byte)0x27,
(byte)0x94,(byte)0xF5,(byte)0x18,(byte)0x70,(byte)0xEF,(byte)0x71,(byte)0x72,(byte)0x7D,
(byte)0xBA,(byte)0x8D,(byte)0xBF,(byte)0x4F,(byte)0x61,(byte)0xC9,(byte)0xA8,(byte)0xE9,
(byte)0xFF,(byte)0x19,(byte)0xF9,(byte)0xF9,(byte)0xE2,(byte)0xD2
};
// ======================================
// 运行时缓冲放RAM避免写EEPROM
private final byte[] buf1; // Enc(Input)
private final byte[] buf2; // Enc(Enc(Input)) -> 应为 Input
private final Zuc256EncryptCtx ctx;
public Method() {
short L = (short) INPUT.length;
buf1 = JCSystem.makeTransientByteArray(L, JCSystem.CLEAR_ON_DESELECT);
buf2 = JCSystem.makeTransientByteArray(L, JCSystem.CLEAR_ON_DESELECT);
ctx = new Zuc256EncryptCtx(); // 仅创建一次
}
public void processData(APDU apdu) {
short L = (short) INPUT.length;
byte[] buf1; // Enc(Input)
byte[] buf2; // Enc(Enc(Input)) -> 应为 Input
buf1 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
buf2 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
byte[] apduBuf = apdu.getBuffer();
// 第一次Enc(Input)
ctx.init(KEY32, IV25);
Zuc256State tmpState = ctx.state;
ctx.update(INPUT, (short) INPUT.length, buf1);
ctx.finish(buf1); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥
Zuc256State tmpState2 = ctx.state;
boolean encMatch = (Util.arrayCompare(buf1, (short)0, ENC_EXPECTED, (short)0, (short)INPUT.length) == 0);
// 第二次Enc(Enc(Input)) 应还原 Input