Files
se-algo/Project/Src/com/cscn/Method.java
2025-09-08 15:35:28 +08:00

100 lines
3.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.cscn;
import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
/**
* 仅做一次“自检调用”:
* 1) ctx.init(KEY, IV); Enc(Input) == EncExpected ?
* 2) ctx.init(KEY, IV); Enc(Enc(Input)) == Input ?
* Response: 2字节 [encMatch, dblEncRestored]1=真0=假
*/
public final class Method {
// ======= 已按你提供的数据填充 =======
// Key: 32字节
private static final byte[] KEY32 = new byte[] {
(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: 你提供的是23字节如需25字节请补齐两字节
private static final byte[] IV25 = new byte[] {
(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: 明文38字节
private static final byte[] INPUT = new byte[] {
(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: 期望密文38字节
private static final byte[] ENC_EXPECTED = new byte[] {
(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 Zuc256EncryptCtx ctx;
public Method() {
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
ctx.init(KEY32, IV25);
ctx.update(buf1, (short) INPUT.length, buf2);
ctx.finish(buf2);
boolean dblOk = (Util.arrayCompare(buf2, (short)0, INPUT, (short)0, (short)INPUT.length) == 0);
// 返回 2 字节结果:[encMatch, dblOk]1=真, 0=假
apduBuf[0] = (byte)(encMatch ? 1 : 0);
apduBuf[1] = (byte)(dblOk ? 1 : 0);
short outLen = 2;
apdu.setOutgoing();
apdu.setOutgoingLength(outLen);
apdu.sendBytes((short)0, outLen);
}
// 本任务不需要更新Key这里留空
public void updateKey(APDU apdu) {
ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
}
}