Arrays 如何将数据数组发送到我的小程序,并由小程序对其进行操作,并在apdu响应中返回新数据?
更新1: 我在javacard上安装了我的小程序(我使用的源代码是我的问题中公认的答案)。当我通过OpenSc发送generatedKey命令时,它只返回9000作为响应,而不是发送XORed数据!我用Javacard版本2.2.1创建了我的项目,我确信我的卡与该版本兼容。为什么OpenSc没有收到预期的数据Arrays 如何将数据数组发送到我的小程序,并由小程序对其进行操作,并在apdu响应中返回新数据?,arrays,applet,javacard,apdu,Arrays,Applet,Javacard,Apdu,更新1: 我在javacard上安装了我的小程序(我使用的源代码是我的问题中公认的答案)。当我通过OpenSc发送generatedKey命令时,它只返回9000作为响应,而不是发送XORed数据!我用Javacard版本2.2.1创建了我的项目,我确信我的卡与该版本兼容。为什么OpenSc没有收到预期的数据 我想向我的JavaCard小程序发送一个包含24个元素的随机字节数组,然后我的小程序应该使用特定的方法更改该数组。例如,该方法将每个元素与0x05异或,并在APDU响应中返回结果数组 为
我想向我的JavaCard小程序发送一个包含24个元素的随机字节数组,然后我的小程序应该使用特定的方法更改该数组。例如,该方法将每个元素与
0x05
异或,并在APDU响应中返回结果数组
为了实现上述目标,到目前为止,我编写了以下程序:
package keyGeneratorPackage;
import javacard.framework.*;
public class keyGeneratorPackage extends Applet {
private static final byte HW_CLA = (byte) 0x80;
private static final byte HW_INS = (byte) 0x00;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new keyGeneratorPackage().register(bArray, (short) (bOffset + 1),
bArray[bOffset]);
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS] & 0xFF);
byte[] Data = new byte[] { (byte) (buffer[ISO7816.OFFSET_CDATA] & 0xFF) };
if (CLA != HW_CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch (INS) {
case HW_INS:
getKey(apdu, Data);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void getKey(APDU apdu, byte[] data) {
byte[] buffer = apdu.getBuffer();
byte[] generatedKey = generateKey(data);
short length = (short) generatedKey.length;
Util.arrayCopyNonAtomic(generatedKey, (short) 0, buffer, (short) 0,
(short) length);
apdu.setOutgoingAndSend((short) 0, length);
}
private byte[] generateKey(byte[] Data) {
byte[] key = new byte[] { (byte) 0x00 };
for (int i = 0; i < Data.length; i++) {
key[i] = (byte) (Data[i] ^ 5);
}
return key;
}
}
包密钥生成器包;
导入javacard.framework.*;
公共类keyGeneratorPackage扩展小程序{
私有静态最终字节HW_CLA=(字节)0x80;
私有静态最终字节HW_INS=(字节)0x00;
公共静态无效安装(字节[]bArray,短bOffset,字节bLength){
新的keyGeneratorPackage().寄存器(bArray,(短)(bOffset+1),
巴里[博夫特];
}
公共作废流程(APDU APDU){
如果(选择Applet()){
返回;
}
byte[]buffer=apdu.getBuffer();
字节CLA=(字节)(缓冲区[ISO7816.OFFSET_CLA]&0xFF);
字节INS=(字节)(缓冲区[ISO7816.OFFSET_INS]&0xFF);
字节[]数据=新字节[]{(字节)(缓冲区[ISO7816.OFFSET\U CDATA]&0xFF)};
如果(CLA!=HW_CLA){
ISOException.throwIt(不支持ISO7816.SW_CLA_);
}
开关(INS){
案例硬件插件:
getKey(apdu,数据);
打破
违约:
ISOException.throwIt(ISO7816.SW不支持);
}
}
私有void getKey(APDU APDU,字节[]数据){
byte[]buffer=apdu.getBuffer();
字节[]生成键=生成键(数据);
短长度=(短)generatedKey.length;
Util.arrayCopyNonAtomic(generatedKey,(short)0,buffer,(short)0,
(短)长度);
apdu.setOutgoingAndSend((短)0,长度);
}
专用字节[]生成键(字节[]数据){
字节[]键=新字节[]{(字节)0x00};
对于(int i=0;i
编译并选择小程序后,我必须发送以下APDU命令:
>>80 00 00 00 18 11 22 33 44 55 66 77 88 99 10 20 30 40 50 60 70 80 90 b1 b2 b3 b4 b5 b6 b7 26
我的小程序有问题吗?在方法中,
私有void getKey(APDU APDU,byte[]data)
您需要调用
apdu.setIncomingAndReceive();
记住:
这是主要的接收方法。调用此方法表示此APDU具有传入数据。此方法获取尽可能多的字节,以便在标头后面的APDU缓冲区中不出现缓冲区溢出。如果合适,它将获取所有传入的字节
因此,请按如下方式更新您的方法:
private void getKey( APDU apdu , byte[] data)
{
apdu.setIncomingAndReceive();
byte[] buffer = apdu.getBuffer();
byte[] generatedKey = generateKey(data);
short length = (short) generatedKey.length;
//short length =1;
Util.arrayCopyNonAtomic(generatedKey, (short)0, buffer, (short)0, (short) length);
apdu.setOutgoingAndSend((short)0, length);
}
注意:setIncomingAndReceive
方法在Applet.process()方法中只能调用一次。有关更多详细信息,请阅读
编辑:代码中有几个问题。我一个接一个地提到它们
问题1:
byte[]Data=newbyte[]{(byte)(缓冲区[ISO7816.OFFSET\U CDATA]&0xFF)}代码>
它创建长度为1的字节[]数据
,值为0x11
解决方案:
new
为数据的持久EEP内存创建空间。如果不再需要数据
,则可以将其设置为瞬态
字节数组
像这样重写它(持久):
或者这个(暂时的):
问题2:
i) 您的generateKey()
方法将崩溃,因为您正在创建byte[]key
,这与您对byte[]Data
所做的相同
ii)您不能声明int i
,因为只有少数卡支持它,请使用byte
或short
解决方案:据我所知,在generateKey()
方法中,您想做什么,我将其改写如下:
// the byte array preparation of key is the callers duty
private byte[] generateKey(byte[] Data, byte[] key) {
short i;
for (i = 0; i < Data.length; i++) {
key[i] = (byte) (Data[i] ^ (byte)0x05);
}
return key;
}
//键的字节数组准备是调用者的职责
专用字节[]生成键(字节[]数据,字节[]键){
短i;
对于(i=0;i
完整的工作代码为:
JavaCard:v.2.2.2
全球平台:v.2.1.1
建议:首先仔细阅读文档
package keyGeneratorPackage;
import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
/**
* KeyGeneratorPackage <br>
*
* @author rakeb.void
*
*/
public class KeyGeneratorPackage extends Applet {
private static final byte HW_CLA = (byte) 0x80;
private static final byte HW_INS = (byte) 0x00;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new keyGeneratorPackage.KeyGeneratorPackage().register(bArray, (short) (bOffset + 1),
bArray[bOffset]);
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
apdu.setIncomingAndReceive();
byte[] buffer = apdu.getBuffer();
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS] & 0xFF);
short lc = (short) (buffer[ISO7816.OFFSET_LC] & (short)0x00FF);
// byte[] Data = new byte[(byte) (buffer[ISO7816.OFFSET_LC] & 0xFF)];
byte[] Data = JCSystem.makeTransientByteArray(lc, JCSystem.CLEAR_ON_DESELECT);
if (CLA != HW_CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch (INS) {
case HW_INS: {
// copying the apdu data into byte array Data
Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, Data, (short) 0, lc);
getKey(apdu, Data);
}
// you forget to put a break here!
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void getKey(APDU apdu, byte[] data) {
byte[] buffer = apdu.getBuffer();
short length = (short) data.length;
//prepareing the key array of same length of Data
byte[] key = JCSystem.makeTransientByteArray(length, JCSystem.CLEAR_ON_DESELECT);
// byte[] generatedKey = generateKey(data, key);
// no need another array generatedKey, as we are passing key as parameter
generateKey(data, key);
// length = (short) generatedKey.length;
Util.arrayCopyNonAtomic(key, (short) 0, buffer, (short) 0, (short) length);
apdu.setOutgoingAndSend((short) 0, length);
}
// .....................................
private byte[] generateKey(byte[] Data, byte[] key) {
short i;
for (i = 0; i < Data.length; i++) {
// i've no idea why you use 0x05 here,
// in the question you mentioned 0x9D
key[i] = (byte) (Data[i] ^ (byte)0x05);
}
return key;
}
}
包密钥生成器包;
导入javacard.framework.APDU;
导入javacard.framework.ISO7816;
导入javacard.framework.Applet;
导入javacard.framework.ISOException;
导入javacard.framework.JCSystem;
导入javacard.framework.Util;
/**
*KeyGeneratorPackage
*
*@author rakeb.void
*
*/
公共类KeyGeneratorPackage扩展小程序{
私有静态最终字节HW_CLA=(字节)0x80;
私有静态最终字节HW_INS=(字节)0x00;
公共静态无效安装(字节[]bArray,短bOffset,字节bLength){
新的keyGeneratorPackage.keyGeneratorPackage()寄存器(bArray,(短)(bOffset+1),
巴里[博夫特];
}
公共作废流程(APDU APDU){
如果(选择Applet()){
返回;
}
apdu.setIncomingAndReceive();
byte[]buffer=apdu.getBuffer();
字节CLA=(字节)(缓冲区[ISO7816.OFFSET_CLA]&0xFF);
字节INS=(字节)(缓冲区[ISO7816.OFFSET_INS]&0xFF);
短lc=(短)(缓冲区[ISO7816.OFFSET_lc]&(短)0x00FF);
//字节[]数据=新字节[(字节)(缓冲区[ISO7816.OFFSET_LC]&0xFF];
// the byte array preparation of key is the callers duty
private byte[] generateKey(byte[] Data, byte[] key) {
short i;
for (i = 0; i < Data.length; i++) {
key[i] = (byte) (Data[i] ^ (byte)0x05);
}
return key;
}
package keyGeneratorPackage;
import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
/**
* KeyGeneratorPackage <br>
*
* @author rakeb.void
*
*/
public class KeyGeneratorPackage extends Applet {
private static final byte HW_CLA = (byte) 0x80;
private static final byte HW_INS = (byte) 0x00;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new keyGeneratorPackage.KeyGeneratorPackage().register(bArray, (short) (bOffset + 1),
bArray[bOffset]);
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
apdu.setIncomingAndReceive();
byte[] buffer = apdu.getBuffer();
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS] & 0xFF);
short lc = (short) (buffer[ISO7816.OFFSET_LC] & (short)0x00FF);
// byte[] Data = new byte[(byte) (buffer[ISO7816.OFFSET_LC] & 0xFF)];
byte[] Data = JCSystem.makeTransientByteArray(lc, JCSystem.CLEAR_ON_DESELECT);
if (CLA != HW_CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch (INS) {
case HW_INS: {
// copying the apdu data into byte array Data
Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, Data, (short) 0, lc);
getKey(apdu, Data);
}
// you forget to put a break here!
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void getKey(APDU apdu, byte[] data) {
byte[] buffer = apdu.getBuffer();
short length = (short) data.length;
//prepareing the key array of same length of Data
byte[] key = JCSystem.makeTransientByteArray(length, JCSystem.CLEAR_ON_DESELECT);
// byte[] generatedKey = generateKey(data, key);
// no need another array generatedKey, as we are passing key as parameter
generateKey(data, key);
// length = (short) generatedKey.length;
Util.arrayCopyNonAtomic(key, (short) 0, buffer, (short) 0, (short) length);
apdu.setOutgoingAndSend((short) 0, length);
}
// .....................................
private byte[] generateKey(byte[] Data, byte[] key) {
short i;
for (i = 0; i < Data.length; i++) {
// i've no idea why you use 0x05 here,
// in the question you mentioned 0x9D
key[i] = (byte) (Data[i] ^ (byte)0x05);
}
return key;
}
}