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); } }