- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 Java Card 2.1.2 SDK 和 GPShell 作为与设备通信的方式在 Java Card 上构建一个项目。我从 GpShell 测试了 helloworld
示例,并成功发送了 Simple APDU 。但是,当我尝试将 APDU 发送到更大的 .cap
文件时,设备给出以下错误
send_APDU() returns 0x8010002F (A communications error with the smart card has b
een detected. Retry the operation.
)
我附上了下面小程序中的代码片段。尽管 Java Card 有 80 Kb EEPROM 和几乎 2 Kb RAM,但在我看来,这是一个内存问题。在 Eclipse 模拟器中,该应用程序运行良好。
TwineCipher.java
public class TwineCipher implements IConsts{
/**
* The 80 bits of cipher twine
*/
public static final short MAX_MEMORY_TEMPORARY=32;
private static TwineCipher ref_twineCipher_80 = null;
private static TwineCipher ref_twineCipher_128 = null;
public byte[] temp = JCSystem.makeTransientByteArray(MAX_MEMORY_TEMPORARY,JCSystem.CLEAR_ON_DESELECT);
public byte[] rk = JCSystem.makeTransientByteArray((short) ((short)36*8),JCSystem.CLEAR_ON_DESELECT);
private static byte [] roundconst =
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x23, 0x05, 0x0a, 0x14, 0x28, 0x13, 0x26,
0x0f, 0x1e, 0x3c, 0x3b, 0x35, 0x29, 0x11, 0x22, 0x07, 0x0e, 0x1c, 0x38, 0x33, 0x25, 0x09, 0x12, 0x24, 0x0b,
};
private static short [] shufinv = {1, 2, 11, 6, 3, 0, 9, 4, 7, 10, 13, 14, 5, 8, 15, 12};
private static short [] shuf = { 5, 0, 1, 4, 7, 12, 3, 8, 13, 6, 9, 2, 15, 10, 11, 14};
private static byte [] sbox = {0x0C, 0x00, 0x0F, 0x0A, 0x02, 0x0B, 0x09, 0x05, 0x08, 0x03, 0x0D, 0x07, 0x01, 0x0E, 0x06, 0x04};
private static byte [] data_enc = new byte[16];
public static TwineCipher getInstance(byte type,byte[] key)
{
switch(type)
{
case TWINE_CIPHER_80:
if(ref_twineCipher_80 != null)
return ref_twineCipher_80;
ref_twineCipher_80 = new TwineCipher(key,TWINE_CIPHER_80);
return ref_twineCipher_80;
case TWINE_CIPHER_128:
if(ref_twineCipher_128 != null)
return ref_twineCipher_128;
ref_twineCipher_128 = new TwineCipher(key,TWINE_CIPHER_128);
return ref_twineCipher_128;
default:
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
}
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
return null;
}
public static TwineCipher getInstance(byte type)
{
switch(type)
{
case TWINE_CIPHER_80:
if(ref_twineCipher_80 != null)
return ref_twineCipher_80;
ref_twineCipher_80 = new TwineCipher();
return ref_twineCipher_80;
case TWINE_CIPHER_128:
if(ref_twineCipher_128 != null)
return ref_twineCipher_128;
ref_twineCipher_128 = new TwineCipher();
return ref_twineCipher_128;
default:
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
}
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
return null;
}
private TwineCipher(byte[] key,byte keySize)
{
switch(keySize)
{
case TWINE_CIPHER_80:
expand80Key(key);
break;
case TWINE_CIPHER_128:
expand128Key(key);
break;
default:
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
}
private TwineCipher()
{
}
private void expand80Key(byte[] key)
{
short len_x = 20;
short key_size = 10;
short iterator = 0,iterator2=0;;
byte temp_val=-1;
byte temp_val2=-1,temp_val3=-1,temp_val4=-1;
short sh=0;
// reset the array
Util.arrayFillNonAtomic(temp, (short)0, (short)20, IConsts.UNTOUCHED_VALUE);
unrowl80ExpandKey(key);
for ( iterator = 0 ; iterator < 35;iterator ++)
{
rk[(short)(iterator * 8 + 0)] = temp[1];
rk[(short)(iterator * 8 + 1)] = temp[3];
rk[(short)(iterator * 8 + 2)] = temp[4];
rk[(short)(iterator * 8 + 3)] = temp[6];
rk[(short)(iterator * 8 + 4)] = temp[13];
rk[(short)(iterator * 8 + 5)] = temp[14];
rk[(short)(iterator * 8 + 6)] = temp[15];
rk[(short)(iterator * 8 + 7)] = temp[16];
temp[1] ^= sbox[temp[0]];
temp[4] ^= sbox[temp[16]];
temp_val = roundconst[iterator];
temp[7] ^= temp_val >> 3;
temp[19] ^= temp_val & 7;
temp_val = temp[0];
temp_val2 = temp[1];
temp_val3 = temp[2];
temp_val4 = temp[3];
for (iterator2 = 0 ; iterator2 < 4;iterator2++)
{
sh = (short)(iterator2*4);
temp[sh] = temp[(short)(sh+4)];
temp[(short)(sh+1)] = temp[(short)(sh+5)];
temp[(short)(sh+2)] = temp[(short)(sh+6)];
temp[(short)(sh+3)] = temp[(short)(sh+7)];
}
temp[16] = temp_val2;
temp[17] = temp_val3;
temp[18] = temp_val4;
temp[19] = temp_val;
}
rk[(short)(35 * 8 + 0)] = temp[1];
rk[(short)(35 * 8 + 1)] = temp[3];
rk[(short)(35 * 8 + 2)] = temp[4];
rk[(short)(35 * 8 + 3)] = temp[6];
rk[(short)(35 * 8 + 4)] = temp[13];
rk[(short)(35 * 8 + 5)] = temp[14];
rk[(short)(35 * 8 + 6)] = temp[15];
rk[(short)(35 * 8 + 7)] = temp[16];
}
private void expand128Key(byte[] key)
{
}
public byte[] encrypt(byte[] src,byte[] dest,short len_src)
{
Util.arrayFillNonAtomic(temp, (short)0, (short)32, IConsts.UNTOUCHED_VALUE); //reset all values
// 16 bytes for first part
// 16 bytes for next
short iterator=0,iterator2=0,iterator3=0;
short START_ITERATOR = 16;
for( iterator = 0 ; iterator < len_src ; iterator++)
{
temp[(short)(2*iterator)] = (byte)((short) (src[iterator] & 0x00FF) >> 4);
temp[(short)(2*iterator+1)] = (byte)((short) (src[iterator] & 0x00FF) & 0x0F);
}
for ( iterator = 0 ; iterator < 35 ; iterator ++)
{
for ( iterator2 = 0 ; iterator2 < 8 ; iterator2 ++)
{
temp[(short)(2*iterator2+1)] ^= sbox[temp[(short)(2*iterator2)] ^ rk[(short)(iterator*8+iterator2)]];
}
for (iterator3 = 0 ; iterator3 < 16;iterator3++)
{
temp[(short)(shuf[iterator3]+16)] = temp[(short)(iterator3)];
}
Util.arrayCopy(temp, (short)16, temp, (short)0, (short)16);
}
iterator = 35;
for (iterator2 = 0; iterator2 < 8 ;iterator2++)
{
temp[(short)(2*iterator2+1)] ^= sbox[temp[(short)(2*iterator2)]^ rk[(short)(iterator*8+iterator2)]];
}
for ( iterator = 0 ;iterator < 8 ;iterator++)
{
temp[(short)(24+iterator)] = (byte)(temp[(short)(2*iterator)] << 4 | temp[(short)(2*iterator + 1)]);
}
Util.arrayCopy(temp, (short)24, dest, (short)(ISO7816.OFFSET_CDATA), (short)8);
return temp; // returns bytes from 24 to 32
}
public byte[] decrypt(byte[] src,byte[] dest,short len_src)
{
// for this alg len_src is always 8
Util.arrayFillNonAtomic(temp, (short)0, (short)32, IConsts.UNTOUCHED_VALUE); //reset all values
short iterator=0,iterator2=0,iterator3=0;
short START_ITERATOR = 16;
for( iterator = 0 ; iterator < len_src ; iterator++)
{
temp[(short)(2*iterator)] = (byte)((short) (src[iterator] & 0x00FF) >> 4);
temp[(short)(2*iterator+1)] = (byte)((short) (src[iterator] & 0x00FF) & 0x0F);
}
for ( iterator = 35 ; iterator > 0 ; iterator --)
{
for ( iterator2 = 0 ; iterator2 < 8 ; iterator2 ++)
{
temp[(short)(2*iterator2+1)] ^= sbox[temp[(short)(2*iterator2)]^ rk[(short)(iterator*8+iterator2)]];
}
for (iterator3 = 0 ; iterator3 < 16;iterator3++)
{
temp[(short)(shufinv[iterator3]+16)] = temp[(short)(iterator3)];
}
Util.arrayCopy(temp, (short)16, temp, (short)0, (short)16);
}
//FINAL
iterator = 0;
for (iterator2 = 0; iterator2 < 8 ;iterator2++)
{
temp[(short)(2*iterator2+1)] ^= sbox[temp[(short)(2*iterator2)]^ rk[(short)(iterator*8+iterator2)]];
}
for ( iterator = 0 ;iterator < 8 ;iterator++)
{
temp[(short)(24+iterator)] = (byte)(temp[(short)(2*iterator)] << 4 | temp[(short)(2*iterator + 1)]);
}
Util.arrayCopy(temp, (short)24, dest, (short)(ISO7816.OFFSET_CDATA), (short)8);
return temp; // returns bytes from 24 to 32 indexes
}
public short process(byte type,byte[] data,short start_offset,short len_data)
{
Util.arrayCopy(data, start_offset, data_enc, (short) 0, len_data);
switch(type)
{
case OFFSET_P1_ENC:
encrypt(data_enc, data, len_data);
return (short)8;
case OFFSET_P1_DEC:
decrypt(data_enc, data, len_data);
return (short)8;
case OFFSET_P1_GEN:
expand80Key(data_enc);
return 10;
default:
return (short)-1;
}
}
private void unrowl80ExpandKey(byte[] key)
{
temp[(short)(2*0)] = (byte)((short) (key[0] & 0x00FF) >> 4);
temp[(short)(2*0 + 1)] = (byte)((short) (key[0] & 0x00FF) & 0x0F);
temp[(short)(2*1)] = (byte)((short) (key[1] & 0x00FF) >> 4);
temp[(short)(2*1 + 1)] = (byte)((short) (key[1] & 0x00FF) & 0x0F);
temp[(short)(2*2)] = (byte)((short) (key[2] & 0x00FF) >> 4);
temp[(short)(2*2 + 1)] = (byte)((short) (key[2] & 0x00FF) & 0x0F);
temp[(short)(2*3)] = (byte)((short) (key[3] & 0x00FF) >> 4);
temp[(short)(2*3 + 1)] = (byte)((short) (key[3] & 0x00FF) & 0x0F);
temp[(short)(2*4)] = (byte)((short) (key[4] & 0x00FF) >> 4);
temp[(short)(2*4 + 1)] = (byte)((short) (key[4] & 0x00FF) & 0x0F);
temp[(short)(2*5)] = (byte)((short) (key[5] & 0x00FF) >> 4);
temp[(short)(2*5 + 1)] = (byte)((short) (key[5] & 0x00FF) & 0x0F);
temp[(short)(2*6)] = (byte)((short) (key[6] & 0x00FF) >> 4);
temp[(short)(2*6 + 1)] = (byte)((short) (key[6] & 0x00FF) & 0x0F);
temp[(short)(2*7)] = (byte)((short) (key[7] & 0x00FF) >> 4);
temp[(short)(2*7 + 1)] = (byte)((short) (key[7] & 0x00FF) & 0x0F);
temp[(short)(2*8)] = (byte)((short) (key[8] & 0x00FF) >> 4);
temp[(short)(2*8 + 1)] = (byte)((short) (key[8] & 0x00FF) & 0x0F);
temp[(short)(2*9)] = (byte)((short) (key[9] & 0x00FF) >> 4);
temp[(short)(2*9 + 1)] = (byte)((short) (key[9] & 0x00FF) & 0x0F);
}
}
IConst.java接口(interface)
public interface IConsts
{
public static final byte UNTOUCHED_VALUE = 0x50;
public static final byte TRUE = 0x01;
public static final byte FALSE = 0x00;
public static final byte OFFSET_CLA_CIPHERS = (byte) 0x00;
public static final byte OFFSET_INS_LIGHT = (byte) 0x11;
public static final byte OFFSET_P1_ENC = (byte) 0x21;
public static final byte OFFSET_P1_DEC = (byte) 0x22;
public static final byte OFFSET_P1_GEN = (byte) 0x23;
public static final byte TWINE_CIPHER_80=0x30;
public static final byte TWINE_CIPHER_128=0x31;
public static final byte LBLOCK_CIPHER=0x32;
}
LBlockCipher.java
public class LBlockCipher implements IConsts {
public static final byte LBLOCK_NBROUNDS = 32;
public static final byte LBLOCK_KEY_SIZE = 80;
public static final short MEMORY_OUTPUT=32*4;
public static final short MEMORY_TEMPORARY=32;
static final byte[] S0 = { 14, 9, 15, 0, 13, 4, 10, 11, 1, 2, 8, 3, 7, 6, 12, 5};
static final byte[] S1 = { 4, 11, 14, 9, 15, 13, 0, 10, 7, 12, 5, 6, 2, 8, 1, 3 };
static final byte[] S2 = { 1, 14, 7, 12, 15, 13, 0, 6, 11, 5, 9, 3, 2, 4, 8, 10 };
static final byte[] S3 = { 7, 6, 8, 11, 0, 15, 3, 14, 9, 10, 12, 13, 5, 2, 4, 1 };
static final byte[] S4 = { 14, 5, 15, 0, 7, 2, 12, 13, 1, 8, 4, 9, 11, 10, 6, 3 };
static final byte[] S5 = { 2, 13, 11, 12, 15, 14, 0, 9, 7, 10, 6, 3, 1, 8, 4, 5 };
static final byte[] S6 = { 11, 9, 4, 14, 0, 15, 10, 13, 6, 12, 5, 7, 3, 8, 1, 2 };
static final byte[] S7 = { 13, 10, 15, 0, 14, 4, 9, 11, 2, 1, 8, 3, 7, 5, 12, 6 };
static final byte[] S8 = { 8, 7, 14, 5, 15, 13, 0, 6, 11, 12, 9, 10, 2, 4, 1, 3 };
static final byte[] S9 = { 11, 5, 15, 0, 7, 2, 9, 13, 4, 8, 1, 12, 14, 10, 3, 6 };
public byte[] output = JCSystem.makeTransientByteArray(MEMORY_OUTPUT,JCSystem.CLEAR_ON_DESELECT);
public byte[] temp = JCSystem.makeTransientByteArray(MEMORY_TEMPORARY,JCSystem.CLEAR_ON_DESELECT);
private static LBlockCipher m_instance_Cipher = null;
public void keySchedule(byte[] key,short start_offset)
{
// use for keyR offset temp [0 - 3 ]
short i = 0 ;
output[(short)(0*4+3)] = key[(short)(9 + start_offset)];
output[(short)(0*4+2)] = key[(short)(8 + start_offset)];
output[(short)(0*4+1)] = key[(short)(7 + start_offset)];
output[(short)(0*4+0)] = key[(short)(6 + start_offset)];
for ( i = 1;i<32;i++)
{
temp[3] = key[(short)(9 + start_offset)];
temp[2] = key[(short)(8 + start_offset)];
temp[1] = key[(short)(7 + start_offset)];
temp[0] = key[(short)(6 + start_offset)];
key[(short)(9 + start_offset)] = (byte) ((((key[(short)(6 + start_offset)] & 0x07) << 5)
& 0xE0) ^ (((key[(short)(5 + start_offset)] & 0xF8) >> 3) & 0x1F));
key[(short)(8 + start_offset)] = (byte) ((((key[(short)(5 + start_offset)]
& 0x07) << 5) & 0xE0) ^ (((key[(short)(4 + start_offset)] & 0xF8) >> 3) & 0x1F));
key[(short)(7 + start_offset)] = (byte) ((((key[(short)(4 + start_offset)]
& 0x07) << 5) & 0xE0) ^ (((key[(short)(3 + start_offset)] & 0xF8) >> 3) & 0x1F));
key[(short)(6 + start_offset)] = (byte) ((((key[(short)(3 + start_offset)]
& 0x07) << 5) & 0xE0) ^ (((key[(short)(2 + start_offset)] & 0xF8) >> 3) & 0x1F));
key[(short)(5 + start_offset)] = (byte) ((((key[(short)(2 + start_offset)] & 0x07) << 5)
& 0xE0) ^ (((key[(short)(1 + start_offset)] & 0xF8) >> 3) & 0x1F));
key[(short)(4 + start_offset)] = (byte) ((((key[(short)(1 + start_offset)] & 0x07) << 5)
& 0xE0) ^ (((key[(short)(0 + start_offset)] & 0xF8) >> 3) & 0x1F));
key[(short)(3 + start_offset)] = (byte) ((((key[(short)(0 + start_offset)] & 0x07) << 5)
& 0xE0) ^ (((temp[3] & 0xF8) >> 3) & 0x1F));
key[(short)(2 + start_offset)] = (byte) ((((temp[3] & 0x07) << 5) & 0xE0) ^ (((temp[2] & 0xF8) >> 3) & 0x1F));
key[(short)(1 + start_offset)] = (byte) ((((temp[2] & 0x07) << 5) & 0xE0) ^ (((temp[1] & 0xF8) >> 3) & 0x1F));
key[(short)(0 + start_offset)] = (byte) ((((temp[1] & 0x07) << 5) & 0xE0) ^ (((temp[0] & 0xF8) >> 3) & 0x1F));
key[(short)(9 + start_offset)] = (byte) ((S9[((key[(short)(9 + start_offset)] >> 4) & 0x0F)] << 4)
^ S8[(key[(short)(9 + start_offset)] & 0x0F)]);
key[(short)(6 + start_offset)] = (byte) (key[(short)(6 + start_offset)] ^ ((i >> 2) & 0x07));
key[(short)(5 + start_offset)] = (byte) (key[(short)(5 + start_offset)] ^ ((i & 0x03) << 6));
output[(short)(i*4 + 3)] = key[(short)(9 + start_offset)];
output[(short)(i*4 + 2)] = key[(short)(8 + start_offset)];
output[(short)(i*4 + 1)] = key[(short)(7 + start_offset)];
output[(short)(i*4 + 0)] = key[(short)(6 + start_offset)];;
}
}
public void OneRound(byte[] x,byte[] k,short offset,short offset_x)
{
// t - from 5 - 8 tmp from 9 to 12
// u8 t[4], tmp[4];
temp[9] = x[(short)(4 + offset_x)];
temp[10] = x[(short)(5 + offset_x)];
temp[11] = x[(short)(6 + offset_x)];
temp[12] = x[(short)(7 + offset_x)];
x[(short)(4 + offset_x)] ^= k[offset];
x[(short)(5 + offset_x)] ^= k[(short)(offset+1)];
x[(short)(6 + offset_x)] ^= k[(short)(offset+2)];
x[(short)(7 + offset_x)] ^= k[(short)(offset+3)];
x[(short)(4 + offset_x)] = (byte) (((S1[((x[(short)(4 + offset_x)]) >> 4) & 0x0F]) << 4)
^ S0[(x[(short)(4 + offset_x)] & 0x0F)]);
x[(short)(5 + offset_x)] = (byte) (((S3[((x[(short)(5 + offset_x)]) >> 4) & 0x0F]) << 4)
^ S2[(x[(short)(5 + offset_x)] & 0x0F)]);
x[(short)(6 + offset_x)] = (byte) (((S5[((x[(short)(6 + offset_x)]) >> 4) & 0x0F]) << 4)
^ S4[(x[(short)(6 + offset_x)] & 0x0F)]);
x[(short)(7 + offset_x)]= (byte) (((S7[((x[(short)(7 + offset_x)]) >> 4) & 0x0F]) << 4)
^ S6[(x[(short)(7 + offset_x)] & 0x0F)]);
temp[5] = (byte) (((x[(short)(4 + offset_x)] >> 4) & 0x0F) ^ (x[(short)(5 + offset_x)] & 0xF0));
temp[6] = (byte) ((x[(short)(4 + offset_x)] & 0x0F) ^ ((x[(short)(5 + offset_x)] & 0x0F) << 4));
temp[7] = (byte) (((x[(short)(6 + offset_x)] >> 4) & 0x0F) ^ (x[(short)(7 + offset_x)] & 0xF0));
temp[8] = (byte) ((x[(short)(6 + offset_x)] & 0x0F) ^ ((x[(short)(7 + offset_x)] & 0x0F) << 4));
x[(short)(4 + offset_x)] = (byte) (x[(short)(3 + offset_x)] ^ temp[5]);
x[(short)(5 + offset_x)] = (byte) (x[(short)(0 + offset_x)] ^ temp[6]);
x[(short)(6 + offset_x)] = (byte) (x[(short)(1 + offset_x)] ^ temp[7]);
x[(short)(7 + offset_x)] = (byte) (x[(short)(2 + offset_x)] ^ temp[8]);
x[(short)(0 + offset_x)] = temp[9];
x[(short)(1 + offset_x)] = temp[10];
x[(short)(2 + offset_x)] = temp[11];
x[(short)(3 + offset_x)] = temp[12];
}
public void encrypt(byte[] x,short offset_x)
{
short i;
for (i = 0; i<32; i++)
{
OneRound(x,output,(short)(4*i),offset_x);
}
}
public void OneRoundInv(byte[] y, byte[] k,short offset,short offset_y)
{
// t - from 5 - 8 tmp from 9 to 12
// u8 t[4], tmp[4];
temp[9] = y[(short)(0 + offset_y)];
temp[10] = y[(short)(1 + offset_y)];
temp[11] = y[(short)(2 + offset_y)];
temp[12] = y[(short)(3 + offset_y)];
y[(short)(0 + offset_y)] = (byte) (y[(short)(0 + offset_y)] ^ k[offset]);
y[(short)(1 + offset_y)] = (byte) (y[(short)(1 + offset_y)] ^ k[(short)(offset+1)]);
y[(short)(2 + offset_y)] = (byte) (y[(short)(2 + offset_y)] ^ k[(short)(offset+2)]);
y[(short)(3 + offset_y)] = (byte) (y[(short)(3 + offset_y)] ^ k[(short)(offset+3)]);
y[(short)(0 + offset_y)] = (byte) (((S1[((y[(short)(0 + offset_y)]) >> 4) & 0x0F]) << 4) ^ S0[(y[(short)(0 + offset_y)] & 0x0F)]);
y[(short)(1 + offset_y)] = (byte) (((S3[((y[(short)(1 + offset_y)]) >> 4) & 0x0F]) << 4) ^ S2[(y[(short)(1 + offset_y)] & 0x0F)]);
y[(short)(2 + offset_y)] = (byte) (((S5[((y[(short)(2 + offset_y)]) >> 4) & 0x0F]) << 4) ^ S4[(y[(short)(2 + offset_y)] & 0x0F)]);
y[(short)(3 + offset_y)] = (byte) (((S7[((y[(short)(3 + offset_y)]) >> 4) & 0x0F]) << 4) ^ S6[(y[(short)(3 + offset_y)] & 0x0F)]);
temp[5] = (byte) (((y[(short)(0 + offset_y)] >> 4) & 0x0F) ^ (y[(short)(1 + offset_y)] & 0xF0));
temp[6] = (byte) ((y[(short)(0 + offset_y)] & 0x0F) ^ ((y[(short)(1 + offset_y)] & 0x0F) << 4));
temp[7] = (byte) (((y[(short)(2 + offset_y)] >> 4) & 0x0F) ^ (y[(short)(3 + offset_y)] & 0xF0));
temp[8] = (byte) ((y[(short)(2 + offset_y)] & 0x0F) ^ ((y[(short)(3 + offset_y)] & 0x0F) << 4));
y[(short)(0 + offset_y)] = (byte) (y[(short)(5 + offset_y)] ^ temp[6]);
y[(short)(1 + offset_y)] = (byte) (y[(short)(6 + offset_y)] ^ temp[7]);
y[(short)(2 + offset_y)] = (byte) (y[(short)(7 + offset_y)] ^ temp[8]);
y[(short)(3 + offset_y)] = (byte) (y[(short)(4 + offset_y)] ^ temp[5]);
// PARTIE GAUCHE
y[(short)(4 + offset_y)] = temp[9];
y[(short)(5 + offset_y)] = temp[10];
y[(short)(6 + offset_y)] = temp[11];
y[(short)(7 + offset_y)] = temp[12];
}
public void decrypt(byte[] x,short offset_x)
{
short i;
for (i = 31; i >= 0; i--)
{
OneRoundInv(x,output,(short)(i*4),offset_x);
}
}
private LBlockCipher()
{
}
public short process(byte type,byte[] data,short start_offset,short len_data)
{
Util.arrayCopy(data, start_offset, temp, (short) 16, len_data);
switch(type)
{
case OFFSET_P1_ENC:
encrypt(temp,(short)(16));
Util.arrayCopy(temp,(short) 16, data, (short) start_offset, len_data);
return (short)8;
case OFFSET_P1_DEC:
decrypt(temp,(short)(16));
Util.arrayCopy(temp,(short) 16, data, (short) start_offset, len_data);
return (short)8;
case OFFSET_P1_GEN:
keySchedule(temp,(short)(16));
Util.arrayCopy(temp,(short) 16, data, (short) start_offset, len_data);
return 10;
default:
return (short)-1;
}
}
public static LBlockCipher getInstance()
{
if(m_instance_Cipher == null)
m_instance_Cipher = new LBlockCipher();
return m_instance_Cipher;
}
}
TestApplet.java
public class TestApplet extends Applet
implements IConsts {
private TestApplet()
{
}
public static void install(byte bArray[], short bOffset, byte bLength) throws ISOException {
new TestApplet().register();
}
public void process(APDU apdu) throws ISOException {
if (selectingApplet()) {
return;
}
byte[] buf = apdu.getBuffer();
if(buf[ISO7816.OFFSET_CLA] != IConsts.OFFSET_CLA_CIPHERS)
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
switch (buf[ISO7816.OFFSET_INS])
{
case IConsts.OFFSET_INS_LIGHT:
processLight(apdu);
return;
default:
break;
}
}
private void processLight(APDU apdu)
{
//cla and ins are proccessed
byte[] buf = apdu.getBuffer();
byte state = (buf[ISO7816.OFFSET_P1]);
byte type = (buf[ISO7816.OFFSET_P2]);
byte count_data = buf[ISO7816.OFFSET_LC];
if(count_data == 0x00)
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
short len_data = -1;
switch(state)
{
case OFFSET_P1_ENC:
switch(type)
{
case TWINE_CIPHER_80:
TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80);
len_data = m_instance.process(OFFSET_P1_ENC, buf, (short)(ISO7816.OFFSET_CDATA), count_data);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data);
return;
case TWINE_CIPHER_128:
TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); //TODO change that
return;
case LBLOCK_CIPHER:
LBlockCipher m_instance_lblock= LBlockCipher.getInstance();
len_data = m_instance_lblock.process(OFFSET_P1_ENC, buf, (short)(ISO7816.OFFSET_CDATA), count_data);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data);
return;
default:
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
case OFFSET_P1_DEC:
switch(type)
{
case TwineCipher.TWINE_CIPHER_80:
TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80);
len_data = m_instance.process(TwineCipher.OFFSET_P1_DEC, buf, (short)(ISO7816.OFFSET_CDATA), count_data);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data);
return;
case TwineCipher.TWINE_CIPHER_128:
TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); //TODO change that
return;
case LBLOCK_CIPHER:
LBlockCipher m_instance_lblock= LBlockCipher.getInstance();
len_data = m_instance_lblock.process(OFFSET_P1_DEC, buf, (short)(ISO7816.OFFSET_CDATA), count_data);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data);
return;
default:
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
case OFFSET_P1_GEN:
switch(type)
{
case TwineCipher.TWINE_CIPHER_80:
TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80);
len_data = m_instance.process(TwineCipher.OFFSET_P1_GEN, buf, (short)(ISO7816.OFFSET_CDATA), count_data);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data);
return;
case TwineCipher.TWINE_CIPHER_128:
TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); //TODO change that
return;
case LBLOCK_CIPHER:
LBlockCipher m_instance_lblock= LBlockCipher.getInstance();
len_data = m_instance_lblock.process(OFFSET_P1_GEN, buf, (short)(ISO7816.OFFSET_CDATA), count_data);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data);
return;
default:
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
default:
break;
}
}
}
最佳答案
在尝试接收 APDU 缓冲区数据字段中的数据之前,必须调用以下方法:
setIncomingAndReceive()
在 APDU 对象上,否则您将收到错误。
替换:
case OFFSET_P1_GEN:
switch(type)
{
case TwineCipher.TWINE_CIPHER_80:
TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80);
len_data = m_instance.process(TwineCipher.OFFSET_P1_GEN, buf, (short)(ISO7816.OFFSET_CDATA), count_data);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data);
return;
// ......
与
case OFFSET_P1_GEN:
switch(type)
{
case TwineCipher.TWINE_CIPHER_80:
TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80);
apdu.setIncomingAndReceive();
len_data = m_instance.process(TwineCipher.OFFSET_P1_GEN, buf, (short)(ISO7816.OFFSET_CDATA), count_data);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data);
return;
//.....
TestApplet.java 将解决此命令的问题(仅适用于您在问题下的第一条评论中提到的命令,而不适用于其他命令),但效率不高实际上:D。因此,找到一个好的行并将此方法调用放在那里。
关于Java 卡 检测到与智能卡的通信错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36515744/
我正在尝试通过 java smartcardio 读取印度政府标准的“Scosta”智能卡我使用的代码是 package com.example.smartcardreader; import jav
下面的代码适用于 2 个不同的加密智能卡库(certum cryptoCertum3PKCS.dll 和 cencert enigmap11.dll ),但在提供用于 100%正确 有人知道我做错了什
有没有人有阅读 eVRC(电子车辆登记卡)和 JAVA 中的 APD U 命令的经验? 任何例子都会有用。 提前致谢。 最佳答案 我强烈建议您使用 javax.smartcardio 库。请注意,在后
我正在将一个旧项目迁移到 Java,但我遇到了一些有关智能卡访问的问题。由于缺乏文档,我不得不自己寻找解决方法,所以我希望你们能帮助我。 我有一张智能卡和一个用于访问卡功能的 dll 库(中间件)。使
我刚刚开始了解一些智能卡,并且正在使用 pyscard 进行练习。 所以我有 2 个问题(我使用的是 Visa 预付卡): 1)我在网上看到有人说有一个方法可以知道你的卡可以使用哪些选择方式,通过他的
Closed. This question needs debugging details。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic用于堆栈溢出。 6个月前关闭。
我正在使用 BouncycaSTLe 来管理我的项目的加密功能。我设法使用 CMS 进行加密和解密,其中两个 key 都存储在我的文件系统中(.cert 和 .p12)。 这是我实际使用的两个函数:
我正在尝试使用 CredMartialCredential 和 LogonUser 为使用智能卡的用户帐户获取访问 token 。有两个帐户可以使用智能卡进行身份验证(描述(有点)here)。 通过关
我们尝试在 iPhone 上连接 PIV 智能卡。我们已经加载了必要的库并且可以发送命令。使用获取数据和获取响应命令的组合,我们能够从智能卡检索所有相关证书。我们现在尝试发送通用身份验证命令来签署一些
我在使用智能卡签署 PDF 文档时遇到问题。它适用于不合格的证书,但不适用于合格的证书。我正在使用 SunPKCS11 提供程序。这是 CryptoTech 卡。这是代码的一部分,我尝试在该提供程序上
我正在为 ISO 7816 卡编写智能卡程序,我需要更新记录。我用JAVA和javax.smartcardio编写程序图书馆。 我使用以下命令选择文件:ins = 0xA4 我可以使用此命令读取记录:
我正在开发用于读取 EMV 卡的智能卡读卡器。我正在处理一张万事达卡,我试图读取特定记录。结果显示读数很好,但是当我解析结果时,它们似乎不遵循 TLV 标准,其中结果采用 Tag/Template-L
我有一个网络服务器服务,客户端请求智能卡计算并获得结果。在服务器正常运行期间,可用的智能卡数量可能会减少或增加,例如,我可以从读卡器中物理添加或移除智能卡(或许多其他事件......如异常等)。 智能
[我的设置] RDP 客户端 (Win7) ------------------RDP------------------------ -> 带智能卡的远程服务器 (Win2k8R2) 我发现无数的答
我可以毫无问题地从智能卡发送大部分数据。我注意到出于某种原因我总是需要删除 APDU 中的前 6 个字节才能获取真实数据。 但是,当发送一个特定数据时,很难知道该数据在 APDU 中的位置。 这是Ja
我也在使用 C++(Windows API)和 Java 的 SmartCard API。 我在删除操作系统后获取 ATR 时遇到问题。我的申请是为了从智能卡中删除操作系统。当操作系统被删除时,卡的
我正在编写一个Java程序,它使用USB证书(智能卡)进行加密和签名。我有一个共享库(Windows 上为 .dll,Linux 上为 .so),它为硬件实现了 PKCS11。 我正在搜索现有的解决方
我目前可以正确使用 pyscard 与我的智能卡通信,但是当 apdu 大小超过 255 字节时,我需要接收命令的剩余字节。 用什么方法获取 pyscard 中的剩余字节?根据我的理解,sw2 应该是
我必须调用服务器上的脚本(php、jsp - 什么都行)。但是此服务器受客户端身份验证保护。现在我可以使用 P12-Keystore 来完成它。代码: private void install
我正在尝试在 ACOS5-64 智能卡和 OMNIKEY 3121 读卡器上创建 AES 256 key ,使用 python 中的 PKCS11(使用 PyKCS11 库)。到目前为止,所有“标准”
我是一名优秀的程序员,十分优秀!