位置加密applet基本实现,目录下包含c java参考代码、打包工具、说明文档、 #2
@@ -56,7 +56,10 @@ public final class Method {
|
|||||||
// 运行时缓冲:放RAM,避免写EEPROM
|
// 运行时缓冲:放RAM,避免写EEPROM
|
||||||
byte[] ctx_buf;
|
byte[] ctx_buf;
|
||||||
short ctx_buflen;
|
short ctx_buflen;
|
||||||
|
|
||||||
|
//todo test
|
||||||
byte[] buf1; // Enc(Input)
|
byte[] buf1; // Enc(Input)
|
||||||
|
//todo test
|
||||||
byte[] buf2; // Enc(Enc(Input)) -> 应为 Input
|
byte[] buf2; // Enc(Enc(Input)) -> 应为 Input
|
||||||
|
|
||||||
// LFSR: 原 int[16] -> hi/lo 各 16
|
// LFSR: 原 int[16] -> hi/lo 各 16
|
||||||
@@ -242,7 +245,8 @@ public final class Method {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void processData(APDU apdu) {
|
//todo test
|
||||||
|
public void testZuc256(APDU apdu) {
|
||||||
|
|
||||||
byte[] apduBuf = apdu.getBuffer();
|
byte[] apduBuf = apdu.getBuffer();
|
||||||
|
|
||||||
@@ -270,21 +274,20 @@ public final class Method {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fake数据生成函数
|
* encryptLocationZuc256
|
||||||
* 输入: stmsi[6], data[5]
|
* 输入: stmsi[6], data[5]
|
||||||
* 输出: fakedata[5]
|
* 输出: out[5]
|
||||||
*/
|
*/
|
||||||
private void makeFakeData(byte[] stmsi, byte[] data, byte[] fakedata) {
|
private void encryptLocationZuc256(byte[] stmsi, byte[] data, byte[] out) {
|
||||||
// 示例:逐字节异或 stmsi 前5字节
|
initZuc256EncryptCtx(KEY32, IV25);
|
||||||
for (short i = 0; i < (short)5; i++) {
|
updateZuc256EncryptCtx(data, (short) 5, out);
|
||||||
fakedata[i] = (byte)(data[i]);
|
finishZuc256EncryptCtx(out, (short) 5); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APDU处理函数
|
* APDU处理函数
|
||||||
*/
|
*/
|
||||||
public short processDataFake(byte[] buffer, short off, short len, byte[] key_store) {
|
public short locationEncryptZuc(byte[] buffer, short off, short len, byte[] key_store) {
|
||||||
// 至少要有 12 个字节:1+1+1+6+5
|
// 至少要有 12 个字节:1+1+1+6+5
|
||||||
if (len < (short)12) {
|
if (len < (short)12) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
@@ -302,7 +305,7 @@ public final class Method {
|
|||||||
Util.arrayCopyNonAtomic(buffer, (short)(off + 9), location_data, (short)0, (short)5);
|
Util.arrayCopyNonAtomic(buffer, (short)(off + 9), location_data, (short)0, (short)5);
|
||||||
|
|
||||||
// === 生成 fakedata ===
|
// === 生成 fakedata ===
|
||||||
makeFakeData(stmsi, location_data, location_res_data);
|
encryptLocationZuc256(stmsi, location_data, location_res_data);
|
||||||
|
|
||||||
// === 出参组装 ===
|
// === 出参组装 ===
|
||||||
buffer[(short)(off + 0)] = (byte)0xA1; // 类型
|
buffer[(short)(off + 0)] = (byte)0xA1; // 类型
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import org.globalplatform.SecureChannel;
|
|||||||
*/
|
*/
|
||||||
public class XwSecurity extends Applet {
|
public class XwSecurity extends Applet {
|
||||||
|
|
||||||
public static final byte INS_PROCESS_DATA = (byte)0xE3;
|
//todo test
|
||||||
|
public static final byte INS_PROCESS_DATA_TEST = (byte)0xE3;
|
||||||
|
|
||||||
public static final byte INS_LOCATION_ENCRYPT = (byte)0xCA;
|
public static final byte INS_LOCATION_ENCRYPT = (byte)0xCA;
|
||||||
|
|
||||||
@@ -72,13 +73,14 @@ public class XwSecurity extends Applet {
|
|||||||
// break;
|
// break;
|
||||||
|
|
||||||
|
|
||||||
case INS_PROCESS_DATA:
|
//todo test
|
||||||
method.processData(apdu);
|
case INS_PROCESS_DATA_TEST:
|
||||||
|
method.testZuc256(apdu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case INS_LOCATION_ENCRYPT:
|
case INS_LOCATION_ENCRYPT:
|
||||||
len = method.processDataFake(buf, off, len, key_store_byte);
|
len = method.locationEncryptZuc(buf, off, len, key_store_byte);
|
||||||
apdu.setOutgoingAndSend(off, len);
|
apdu.setOutgoingAndSend(off, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user