写基础Applet,试图测试加解密正确性
This commit is contained in:
BIN
Bat/Delivery/cscn.cap
Normal file
BIN
Bat/Delivery/cscn.cap
Normal file
Binary file not shown.
BIN
Bat/Delivery/cscn.exp
Normal file
BIN
Bat/Delivery/cscn.exp
Normal file
Binary file not shown.
@@ -1,19 +1,97 @@
|
|||||||
package com.cscn;
|
package com.cscn;
|
||||||
|
|
||||||
import javacard.framework.APDU;
|
import javacard.framework.APDU;
|
||||||
|
import javacard.framework.ISO7816;
|
||||||
|
import javacard.framework.ISOException;
|
||||||
|
import javacard.framework.JCSystem;
|
||||||
|
import javacard.framework.Util;
|
||||||
|
|
||||||
public class Method {
|
/**
|
||||||
|
* 仅做一次“自检调用”:
|
||||||
|
* 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 {
|
||||||
|
|
||||||
public void processData(APDU apdu)
|
// ======= 请用你的向量替换下面占位内容 =======
|
||||||
{
|
// Key: 32字节
|
||||||
// TODO Auto-generated method stub
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
// IV: 25字节(ZUC-256)
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
// Input: 建议长度为 4 的倍数,便于不走 finish 的残字节路径
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
// EncResult: 期望密文(与上面的 Input 配套)
|
||||||
|
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
|
||||||
|
};
|
||||||
|
// ======================================
|
||||||
|
|
||||||
|
// 运行时缓冲:放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 updateKey(APDU apdu)
|
public void processData(APDU apdu) {
|
||||||
{
|
byte[] apduBuf = apdu.getBuffer();
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
|
// 第一次:Enc(Input)
|
||||||
|
ctx.init(KEY32, IV25);
|
||||||
|
ctx.update(INPUT, (short) INPUT.length, buf1);
|
||||||
|
ctx.finish(buf1); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,9 +215,13 @@ public final class Zuc256Core {
|
|||||||
|
|
||||||
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||||
// LFSR_lo 向左移
|
// LFSR_lo 向左移
|
||||||
System.arraycopy(state.LFSR_lo, 1, state.LFSR_lo, 0, 15);
|
for (short i = 0; i < (short)15; i++) {
|
||||||
|
state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)];
|
||||||
|
}
|
||||||
// LFSR_hi 向左移
|
// LFSR_hi 向左移
|
||||||
System.arraycopy(state.LFSR_hi, 1, state.LFSR_hi, 0, 15);
|
for (short i = 0; i < (short)15; i++) {
|
||||||
|
state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
// LFSR[15] = v;
|
// LFSR[15] = v;
|
||||||
// ---- 写回 LFSR[15] ----
|
// ---- 写回 LFSR[15] ----
|
||||||
@@ -260,7 +264,7 @@ public final class Zuc256Core {
|
|||||||
|
|
||||||
// 初始化MAC密钥
|
// 初始化MAC密钥
|
||||||
private static void zuc256SetMacKey(Zuc256State state, byte[] K, byte[] IV, short macbits) {
|
private static void zuc256SetMacKey(Zuc256State state, byte[] K, byte[] IV, short macbits) {
|
||||||
short[] D;
|
short[] D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.CLEAR_ON_DESELECT);
|
||||||
short[] TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.CLEAR_ON_DESELECT);
|
short[] TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.CLEAR_ON_DESELECT);
|
||||||
short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.CLEAR_ON_DESELECT);
|
short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.CLEAR_ON_DESELECT);
|
||||||
short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.CLEAR_ON_DESELECT);
|
short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.CLEAR_ON_DESELECT);
|
||||||
@@ -295,11 +299,9 @@ public final class Zuc256Core {
|
|||||||
short IV24 = (short)(IV[22] & 0x3F);
|
short IV24 = (short)(IV[22] & 0x3F);
|
||||||
|
|
||||||
// D = (macbits / 32 < 3) ? Zuc256Tables.ZUC256_D[macbits / 32] : Zuc256Tables.ZUC256_D[3];
|
// D = (macbits / 32 < 3) ? Zuc256Tables.ZUC256_D[macbits / 32] : Zuc256Tables.ZUC256_D[3];
|
||||||
if ((macbits / 32) < 3) {
|
short row = (short)((macbits / 32) < 3 ? (macbits / 32) : 3);
|
||||||
D = Zuc256Tables.ZUC256_D[macbits / 32];
|
Zuc256Tables.getDRow(row, D, (short)0);
|
||||||
} else {
|
Zuc256Tables.getDRow(row, D, (short)0);
|
||||||
D = Zuc256Tables.ZUC256_D[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
short[] tmp = new short[2]; // 临时存储 makeU31 输出 (lo,hi)
|
short[] tmp = new short[2]; // 临时存储 makeU31 输出 (lo,hi)
|
||||||
@@ -462,8 +464,14 @@ public final class Zuc256Core {
|
|||||||
add31(V[0], V[1], T2[0], T2[1], V);
|
add31(V[0], V[1], T2[0], T2[1], V);
|
||||||
|
|
||||||
// System.arraycopy(state.LFSR, 1, state.LFSR, 0, 15)
|
// System.arraycopy(state.LFSR, 1, state.LFSR, 0, 15)
|
||||||
System.arraycopy(state.LFSR_lo, 1, state.LFSR_lo, 0, 15);
|
// 相当于 System.arraycopy(state.LFSR_lo, 1, state.LFSR_lo, 0, 15);
|
||||||
System.arraycopy(state.LFSR_hi, 1, state.LFSR_hi, 0, 15);
|
for (short j = 0; j < (short)15; j++) {
|
||||||
|
state.LFSR_lo[j] = state.LFSR_lo[(short)(j + 1)];
|
||||||
|
}
|
||||||
|
// 相当于 System.arraycopy(state.LFSR_hi, 1, state.LFSR_hi, 0, 15);
|
||||||
|
for (short j = 0; j < (short)15; j++) {
|
||||||
|
state.LFSR_hi[j] = state.LFSR_hi[(short)(j + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
// state.LFSR[15] = v;
|
// state.LFSR[15] = v;
|
||||||
state.LFSR_lo[15] = V[0];
|
state.LFSR_lo[15] = V[0];
|
||||||
@@ -567,9 +575,16 @@ public final class Zuc256Core {
|
|||||||
|
|
||||||
// LFSR左移
|
// LFSR左移
|
||||||
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||||
|
// LFSR_lo 向左移
|
||||||
|
for (short i = 0; i < (short)15; i++) {
|
||||||
|
state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)];
|
||||||
|
}
|
||||||
|
// LFSR_hi 向左移
|
||||||
|
for (short i = 0; i < (short)15; i++) {
|
||||||
|
state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
// LFSR[15] = v;
|
// LFSR[15] = v;
|
||||||
System.arraycopy(state.LFSR_lo, 1, state.LFSR_lo, 0, 15);
|
|
||||||
System.arraycopy(state.LFSR_hi, 1, state.LFSR_hi, 0, 15);
|
|
||||||
state.LFSR_lo[15] = v_lo;
|
state.LFSR_lo[15] = v_lo;
|
||||||
state.LFSR_hi[15] = v_hi;
|
state.LFSR_hi[15] = v_hi;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.cscn;
|
package com.cscn;
|
||||||
|
|
||||||
import javacard.framework.JCSystem;
|
import javacard.framework.JCSystem;
|
||||||
|
import javacard.framework.Util;
|
||||||
|
|
||||||
import static com.cscn.Zuc256Core.zuc256GenerateKeystream;
|
import static com.cscn.Zuc256Core.zuc256GenerateKeystream;
|
||||||
import static com.cscn.Zuc256Core.zuc256GenerateKeyword;
|
import static com.cscn.Zuc256Core.zuc256GenerateKeyword;
|
||||||
@@ -56,7 +57,9 @@ public final class Zuc256EncryptCtx {
|
|||||||
// int copy = Math.min(inlen, need);
|
// int copy = Math.min(inlen, need);
|
||||||
short copy = (short)((inlen < need) ? inlen : need);
|
short copy = (short)((inlen < need) ? inlen : need);
|
||||||
|
|
||||||
System.arraycopy(in, 0, this.buf, this.buflen, copy);
|
// 替代 System.arraycopy(in, 0, this.buf, this.buflen, copy);
|
||||||
|
Util.arrayCopyNonAtomic(in, (short)0, this.buf, this.buflen, copy);
|
||||||
|
|
||||||
this.buflen += copy;
|
this.buflen += copy;
|
||||||
|
|
||||||
// 调整输入指针和长度
|
// 调整输入指针和长度
|
||||||
@@ -152,7 +155,9 @@ public final class Zuc256EncryptCtx {
|
|||||||
|
|
||||||
// 缓存剩余不足4字节的数据
|
// 缓存剩余不足4字节的数据
|
||||||
if (inlen > 0) {
|
if (inlen > 0) {
|
||||||
System.arraycopy(in, 0, this.buf, 0, inlen);
|
// 等价于 System.arraycopy(in, 0, this.buf, 0, inlen);
|
||||||
|
Util.arrayCopyNonAtomic(in, (short)0, this.buf, (short)0, inlen);
|
||||||
|
|
||||||
this.buflen = inlen;
|
this.buflen = inlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,6 +191,7 @@ public final class Zuc256EncryptCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.buflen = 0;
|
this.buflen = 0;
|
||||||
|
|
||||||
// Arrays.fill(this.state.LFSR, 0);
|
// Arrays.fill(this.state.LFSR, 0);
|
||||||
// LFSR 全部清零(高低位数组各 16 个元素)
|
// LFSR 全部清零(高低位数组各 16 个元素)
|
||||||
for (short i = 0; i < 16; i++) {
|
for (short i = 0; i < 16; i++) {
|
||||||
@@ -193,6 +199,7 @@ public final class Zuc256EncryptCtx {
|
|||||||
this.state.LFSR_hi[i] = 0;
|
this.state.LFSR_hi[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this.state.R1 = 0;
|
// this.state.R1 = 0;
|
||||||
// this.state.R2 = 0;
|
// this.state.R2 = 0;
|
||||||
// R1、R2 清零
|
// R1、R2 清零
|
||||||
|
|||||||
@@ -49,13 +49,50 @@ public final class Zuc256Tables {
|
|||||||
0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2
|
0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 常量数组 D(16bit short二维数组适配)
|
// * 常量数组 D(16bit short二维数组适配)
|
||||||
*/
|
// */
|
||||||
public static final short[][] ZUC256_D = {
|
// public static final short[][] ZUC256_D = {
|
||||||
{0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
// {0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
||||||
{0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
// {0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
||||||
{0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
// {0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
||||||
{0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}
|
// {0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}
|
||||||
};
|
// };
|
||||||
|
public static final short D_COLS = 16;
|
||||||
|
/**
|
||||||
|
* 常量数组 D(16bit short二维数组适配)
|
||||||
|
*/
|
||||||
|
public static final short[] ZUC256_D_FLAT = new short[] {
|
||||||
|
// row 0
|
||||||
|
0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,
|
||||||
|
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
|
||||||
|
|
||||||
|
// row 1
|
||||||
|
0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,
|
||||||
|
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
|
||||||
|
|
||||||
|
// row 2
|
||||||
|
0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,
|
||||||
|
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
|
||||||
|
|
||||||
|
// row 3
|
||||||
|
0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,
|
||||||
|
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** 读取 D[row][col],返回无符号值 0..255 */
|
||||||
|
public static short getD(short row, short col) {
|
||||||
|
// idx = row * 16 + col
|
||||||
|
short idx = (short)(row * D_COLS + col);
|
||||||
|
return (short)(ZUC256_D_FLAT[idx] & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 取一行 (返回一段16个short) */
|
||||||
|
public static void getDRow(short row, short[] out, short outOff) {
|
||||||
|
short base = (short)(row * D_COLS);
|
||||||
|
for (short i = 0; i < D_COLS; i++) {
|
||||||
|
out[(short)(outOff + i)] = ZUC256_D_FLAT[(short)(base + i)];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -18,8 +18,8 @@ public final class Zuc256Util {
|
|||||||
// }
|
// }
|
||||||
/** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */
|
/** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */
|
||||||
public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
|
public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
|
||||||
out32[0] = (short) (((p[offset + 2] & 0xFF) << 8) | (p[offset + 3] & 0xFF)); //低16位
|
out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位
|
||||||
out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[offset + 1] & 0xFF)); //高16位
|
out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -34,11 +34,11 @@ public final class Zuc256Util {
|
|||||||
public static void putU32(byte[] p, short offset, short vlo, short vhi) {
|
public static void putU32(byte[] p, short offset, short vlo, short vhi) {
|
||||||
// 写高16位
|
// 写高16位
|
||||||
p[offset] = (byte) ((vhi >> 8) & 0xFF);
|
p[offset] = (byte) ((vhi >> 8) & 0xFF);
|
||||||
p[offset + 1] = (byte) (vhi & 0xFF);
|
p[(short)(offset + 1)] = (byte) (vhi & 0xFF);
|
||||||
|
|
||||||
// 写低16位
|
// 写低16位
|
||||||
p[offset + 2] = (byte) ((vlo >> 8) & 0xFF);
|
p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF);
|
||||||
p[offset + 3] = (byte) (vlo & 0xFF);
|
p[(short)(offset + 3)] = (byte) (vlo & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ public final class Zuc256Util {
|
|||||||
bits[i] = (short)((a_lo >>> i) & 1);
|
bits[i] = (short)((a_lo >>> i) & 1);
|
||||||
}
|
}
|
||||||
for (short i = 0; i < 15; i++) {
|
for (short i = 0; i < 15; i++) {
|
||||||
bits[16 + i] = (short)((a_hi >>> i) & 1);
|
bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 旋转
|
// 旋转
|
||||||
@@ -118,7 +118,7 @@ public final class Zuc256Util {
|
|||||||
}
|
}
|
||||||
short hi = 0;
|
short hi = 0;
|
||||||
for (short i = 0; i < 15; i++) {
|
for (short i = 0; i < 15; i++) {
|
||||||
hi = (short)(hi | (resBits[16 + i] << i));
|
hi = (short)(hi | (resBits[(short)(16 + i)] << i));
|
||||||
}
|
}
|
||||||
|
|
||||||
out[0] = lo;
|
out[0] = lo;
|
||||||
@@ -310,7 +310,7 @@ public final class Zuc256Util {
|
|||||||
// 处理剩余8字节
|
// 处理剩余8字节
|
||||||
byte[] src = new byte[8];
|
byte[] src = new byte[8];
|
||||||
for (short i = 0; i < 8; i++) {
|
for (short i = 0; i < 8; i++) {
|
||||||
src[i] = (byte) (input25Byte[17 + i] & 0x3F);
|
src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F);
|
||||||
}
|
}
|
||||||
|
|
||||||
output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4));
|
output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4));
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.zuc.zuc256;
|
|
||||||
|
|
||||||
import javacard.framework.JCSystem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MAC上下文类(Java Card兼容版本)
|
|
||||||
*/
|
|
||||||
public final class Zuc256MacCtx {
|
|
||||||
// 所有32位int类型改为16位short类型,适应Java Card 16位处理能力
|
|
||||||
short[] LFSR;
|
|
||||||
short R1;
|
|
||||||
short R2;
|
|
||||||
byte[] buf;
|
|
||||||
short buflen; // 长度变量使用short类型
|
|
||||||
short[] T;
|
|
||||||
short[] K0;
|
|
||||||
short macbits; // MAC位数使用short类型
|
|
||||||
|
|
||||||
// 构造函数初始化瞬态数组,符合Java Card内存管理规范
|
|
||||||
public Zuc256MacCtx() {
|
|
||||||
// 使用瞬态内存存储敏感数据,提高安全性
|
|
||||||
// CLEAR_ON_DESELECT:卡片复位或选择其他应用时清除数据
|
|
||||||
LFSR = JCSystem.makeTransientShortArray((short)16, JCSystem.CLEAR_ON_DESELECT);
|
|
||||||
buf = JCSystem.makeTransientByteArray((short)4, JCSystem.CLEAR_ON_DESELECT);
|
|
||||||
T = JCSystem.makeTransientShortArray((short)4, JCSystem.CLEAR_ON_DESELECT);
|
|
||||||
K0 = JCSystem.makeTransientShortArray((short)4, JCSystem.CLEAR_ON_DESELECT);
|
|
||||||
|
|
||||||
// 初始化变量
|
|
||||||
R1 = 0;
|
|
||||||
R2 = 0;
|
|
||||||
buflen = 0;
|
|
||||||
macbits = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package com.zuc.zuc256;
|
|
||||||
|
|
||||||
import javacard.framework.JCSystem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ZUC状态类(Java Card兼容版本)
|
|
||||||
*/
|
|
||||||
public final class Zuc256State {
|
|
||||||
// 适配Java Card 16位处理能力,将int改为short
|
|
||||||
short[] LFSR; // 线性反馈移位寄存器
|
|
||||||
short R1; // 寄存器1
|
|
||||||
short R2; // 寄存器2
|
|
||||||
|
|
||||||
// 构造函数初始化瞬态数组
|
|
||||||
public Zuc256State() {
|
|
||||||
// 创建瞬态short数组,长度16,选择在卡片复位或切换应用时清除
|
|
||||||
LFSR = JCSystem.makeTransientShortArray((short)16, JCSystem.CLEAR_ON_DESELECT);
|
|
||||||
// 初始化寄存器值为0
|
|
||||||
R1 = 0;
|
|
||||||
R2 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user