当前位置: 首页 > news >正文

【Java Card】Applet 使用Shareable进行数据分享以及部分问题处理

文章目录

  • 前言
  • 一、定义接口
  • 二、server端实现
  • 三、client端实现
  • 四、遇到的问题


前言

在进行开发时,可能会将业务放到不同的applet中,这时常常会需要进行数据的分享。
比如在一个applet中存储了密钥,而在另一个业务applet中需要进行签名时,需要将数据传给第一个applet进行签名后,再返回签名后的数据。
这里介绍Java Card中的Shareable的数据分享的方式。

一、定义接口

import javacard.framework.Shareable;public interface DataShareable extends Shareable {public byte getDataInfo(byte[] buffer, short offset, short length);
}

需要继承Java Card的Shareable 类,定义好我们需要的接口,这里定义了getDataInfo方法,用于将数据写到buffer中以提供给client。

二、server端实现

public class DataInfoApplet extends Applet implements DataShareable{byte[] DataInfo;protected DataInfoApplet () {DataInfo = new byte[16];register();}public static void install(byte[] bArray, short bOffset, byte bLength) {new DataInfoApplet ();}@Overridepublic Shareable getShareableInterfaceObject(AID clientAID, byte parameter) {if (!clientAID.equals(sAIDClientApplet, (short) 0, (byte) sAIDClientApplet.length)) {return null;}return this;}@Overridepublic void process(APDU apdu) {}@Overridepublic byte getDataInfo(byte[] out, short offset, short length) {try {Util.arrayCopy(DataInfo, (short) 0, out, offset, length);return OK;} catch (ArrayIndexOutOfBoundsException e) {return NOT_OK;}}
}
  • server端需要实现DataShareable接口。
  • 需要实现getShareableInterfaceObject,该方法会在client端调用JCSystem.getShareableInterfaceObject时执行。在这里面可以进行clientAID的判断,以使得仅有特定的applet才能够调用shareable接口。

三、client端实现

注意:client和server是在不同的package中的。

public class ClientApplet extends Applet {DataShareable sio = null;protected ClientApplet () {register();}public static void install(byte[] bArray, short bOffset, byte bLength) {new ClientApplet ();}private boolean getSIO() {if (this.sio == null) {this.sio = (DataShareable)JCSystem.getAppletShareableInterfaceObject(JCSystem.lookupAID(DATAINFO_APPLET_AID_BYTES,(short)0, (byte)(DATAINFO_APPLET_AID_BYTES.length)),(byte)0);}if(this.sio != null) {return true;} else {return false;}}@Overridepublic void process(APDU apdu) {byte[] buffer = apdu.getBuffer();sio.getDataInfo(buffer , (short) 0, (short) 16);apdu.setOutgoing();apdu.setOutgoingLength((short) 16);apdu.sendBytesLong(buffer , (short) 0, (short) 16);return;}@Overridepublic boolean select() {return getSIO();}@Overridepublic void deselect() {sio = null;}
}
  • getSIO中通过JCSystem.getAppletShareableInterfaceObject来获得接口对象sio。
  • 使用sio来调用接口方法,并传入buffer参数。

四、遇到的问题

1、接口中创建对象失败

@Overridepublic byte getDataInfo(byte[] out, short offset, short length) {try {byte[] temp = JCSystem.makeTransientByteArray((short) 4, JCSystem.CLEAR_ON_DESELECT);Util.arrayCopy(DataInfo, (short) 0, out, offset, length);return OK;} catch (ArrayIndexOutOfBoundsException e) {return NOT_OK;}}

在server实现的接口方法中,添加了byte[] temp = JCSystem.makeTransientByteArray((short) 4, JCSystem.CLEAR_ON_DESELECT);则调用该接口时会报错。

分析:

JCCRE中规定,对于CLEAR_ON_DESELECT类型的瞬态数据,只有当前活动的context是当前选择的applet的context时,才能够创建和使用。

这个案例中,对于两个不同package中的applet进行接口调用时,会进行context的切换,所以调用到getDataInfo接口时,当前活动的context已经切换为了server的context。但是接口是在client处理apdu请求时调用的,此时被选择的applet仍然是client。所以导致前面的条件无法满足,所以出现错误。
在这里插入图片描述
解决:
使用CLEAR_ON_RESET。

byte[] temp = JCSystem.makeTransientByteArray((short) 4, JCSystem.CLEAR_ON_RESET);

CLEAR_ON_RESET类型要求,当前活动的context是对象所有者的context,因此可以在这样的情况下满足条件

2、数据无法通过接口传输

 @Overridepublic void process(APDU apdu) {//byte[] buffer = apdu.getBuffer();byte[] data = JCSystem.makeTransientByteArray((short) 16, JCSystem.CLEAR_ON_RESET);sio.getDataInfo(data , (short) 0, (short) 16);apdu.setOutgoing();apdu.setOutgoingLength((short) 16);apdu.sendBytesLong(data , (short) 0, (short) 16);return;}

如果client中这样写,即使用makeTransientByteArray来创建瞬态数据data并作为参数传递,则调用时会出现数据的访问失败

分析:
在这里插入图片描述
从日志可以看出,是由于临时数据无法在不同的context之间进行访问。临时数据是收到防火墙保护的,这个data数据是属于client的context的,而调用接口后,活动的context切换为了server的context,那么在server中就无法访问这个data,进而无法向其中写入数据。

解决:
使用byte[] buffer = apdu.getBuffer();来进行数据的发送和接收。

 @Overridepublic void process(APDU apdu) {byte[] buffer = apdu.getBuffer();sio.getDataInfo(data , (short) 0, (short) 16);apdu.setOutgoing();apdu.setOutgoingLength((short) 16);apdu.sendBytesLong(data , (short) 0, (short) 16);return;}

apdu.getBuffer() 返回的是 APDU缓冲区,它是一个特殊的 全局缓冲区,在 Java Card 上被认为是跨防火墙允许的共享对象。

http://www.lryc.cn/news/539355.html

相关文章:

  • 国产FPGA开发板选择
  • com.typesafe.config
  • Ubuntu学习备忘
  • 【C++】— 掌握STL vector 类:“Vector简介:动态数组的高效应用”
  • Docker__持续更新......
  • 【R语言】主成分分析与因子分析
  • ROS-相机话题-获取图像-颜色目标识别与定位-目标跟随-人脸检测
  • STM32 如何使用DMA和获取ADC
  • 【JAVA实战】JAVA实现Excel模板下载并填充模板下拉选项数据
  • java面试笔记(一)
  • 【C++】36.C++IO流
  • Qt5开发入门指南:从零开始掌握跨平台开发
  • Rook-ceph(1.92最新版)
  • 深度学习在蛋白质-蛋白质相互作用(PPI)领域的研究进展(2022-2025)
  • 网络安全学习架构 网络安全架构内容
  • 硕成C语言24
  • 《Stable Diffusion绘画完全指南:从入门到精通的Prompt设计艺术》-配套代码示例
  • Linux下为Intel核显安装OpenCL
  • 用deepseek学大模型04-机器学习建模过程
  • 【ClickHouse】Ubuntu下离线安装ClickHouse数据库并使用DBeaver连接
  • Unity3D实现接入DeepSeek对话
  • 【ISO 14229-1:2023 UDS诊断(会话控制0x10服务)测试用例CAPL代码全解析②】
  • 前端新手必看:10 大 UI 组件库全面解析,快速搭建高质量 Web 应用」 「从零开始:Vue 和 React 最受欢迎的 UI 组件库入门指南」 「超实用!PC 端和移动端 UI 组件库推荐与实战
  • 【MySQL高级】17 - MySQL中常用工具
  • 【Linux】Linux 文件系统——有关 inode 不足的案例
  • 计算机视觉:卷积神经网络(CNN)基本概念(二)
  • 【第7章:注意力机制与Transformer模型—7.4 NLP领域的BERT、GPT系列模型】
  • [代码调试]安装Text2Image(stable diffusion)模型环境的踩坑记录
  • 大数据SQL调优专题——Flink执行原理
  • Oracle 12c中在同一组列上创建多个索引