1、 JAVA卡文件系统详细设计1 结构体、变量及常量描述1.1 结构体1.1.1 DF文件头的基本结构1)DF文件头固定部分结构struct DFHEAD u16 fid; / DF IDmemref efhead;/ Handle of the first EF under current DFmemref child_df;/ Handle of the first DF under current DFmemref buddy_df;/ Handle of the next DF which has the same parentmemref parent_df;/ parent DFu8
2、 flag;/ applet dfu8 length; / 后续可变文件头长度;/ 20 bytes参数说明:Flag :DF标志Bit7-bit1 : RUFBit0 : 0 公共DF,1 与APPLET链接的DF2)DF文件头中可变部分结构存放顺序为:u8 aid_length;u8 aidaid_length;DF AIDu8 length_of_extension;u8 extensionlength_of_extension;DF 属性1.1.2 EF文件头的基本结构1)EF文件头固定部分结构struct EFHEAD u16 fid; / EF IDu8 type;/ EF typ
3、e and sfiu8 stu;/ EF memref efhead;/ Handle of the next EF under same parentu8 origin;/ EF current record pointeru8 lenlh;/ EF length, high byteu8 lenll;/ EF length, low byteu8 length_of_ext; / 后续可变文件头长度;/ 11 bytes参数说明:type 的编码格式:0 | file type (2 bit) | SFI(5 bit),file type: = 00,二进制文件 = 01,变长记录文件 =
4、 10,定长记录文件 = 11,循环定长记录文件origin:如果是循环记录文件,则为最近一条记录对应的物理记录号(从1开始编号),如果为0,表示没有记录存在;如果是定长和非定长记录文件,则为文件当前的记录数。lenlh:对定长和循环记录文件,为记录数lenll:对定长和循环记录文件,为记录长度2)EF文件头中可变部分结构存放顺序为:u8 extensionlength_of_extension;EF 属性1.2 变量定义u8 d_nextlen;u8 d_currecno;/ 记录指针u8 d_fileheadSIZE_FILE_HEADER;/ DF/EF 的文件头memref d_dfp
5、ointer;/ 当前DF指针memref d_efpointer;/ 当前EF指针memref d_nextaddr;1.3 常量定义1.3.1 文件头长度#define SIZE_FILE_HEADER(sizeof(u16)+4*sizeof(memref)+2*sizeof(u8) 1.3.2 文件信息/ DF文件头中固定部分结构#define DF_DFHAND0#define DF_EFHAND 4#define DF_NEXTDF8#define DF_PARENTDF12#define DF_FID 16#define DF_FLAG18#define DF_LENGTH19#
6、define DF_AIDLEN SIZE_FILE_HEADER#define DF_AID (SIZE_FILE_HEADER+1)/ DF文件头中可变部分结构#define DF_EXTLENGTH 9#define DF_AC0#define DF_ATR1#define DF_AMD3#define DF_DIR5#define DF_STU6#define DF_BS7#define DF_TYPE 8/ EF文件头中固定部分结构#define EF_FID 0#define EF_TYPE 2#define EF_STU 3#define EF_EFHAND 4#define E
7、F_ORIGIN 8#define EF_LENLH9#define EF_LENLL 10#define EF_EXTLEN 11/ EF文件头中可变部分#define EF_EXTLENGTH 4#define EF_SUBTYPE0#define EF_AC11#define EF_AC22#define EF_AC331.3.3 EF文件类型/文件类型#define EFTYPE_BIN0x00/ Binary file#define EFTYPE_LINEAR0x40/ Linear fixed#define EFTYPE_CHANGE0x20/ Variable file#defi
8、ne EFTYPE_CYCLIC0x60/ Cyclic file/文件类型#define EF_TYPE_BIN0x00/ Binary file#define EF_TYPE_LINEAR0x01/ Linear fixed#define EF_TYPE_CHANGE0x02/ Variable file#define EF_TYPE_CYCLIC0x03/ Cyclic file/ 文件子类型/ EF文件子类型#define EF_SUB_BASIC 0x00/基本文件#define EF_SUB_OBJ 0x01/数据对象文件#define EF_SUB_KEY 0x02/密钥文件#d
9、efine EF_SUB_SK 0x03/私钥文件类型 #define EF_SUB_PK 0x04/公钥文件类型 #define EF_SUB_CER0x05/证书文件类型 #define EF_SUB_PURSE 0x07/银行标准钱包文件#define EF_SUB_DEPOSIT 0x08/银行标准存折文件#define EF_SUB_ENCRYPT 0x09/加密公钥文件类型 #define EF_SUB_DECRYPT 0x0A/解密私钥文件类型 #define EF_SUB_ECCSK0x0B/#define EF_SUB_ECCPK0x0C/ 1.3.4 密钥信息/ 密钥结构#
10、define KEY_ID(0)/ 密钥 ID#define KEY_VERSION(1)/ 密钥版本号#define KEY_ALG(2)/ 密钥算法标识#define KEY_TYPE(3)/ 密钥类型#define KEY_USE_AC(4)/ 密钥使用条件#define KEY_TO_AC(5)/ 密钥后续状态#define KEY_CHG_AC(6)/ 密钥修改条件#define KEY_MAX_COUNT(7)/ 最大错误次数#define KEY_CUR_COUNTKEY_MAX_COUNT/ 当前错误次数#define KEY_VALUE(8)/ 密钥值#define KEY_
11、VALUE1KEY_VALUE/ 密钥1的值#define KEY_VALUE2(16)/ 密钥2的值#define KEY_CHK(24)/ 校验和#define KEY_LENGTH(25)/ Key 记录长度/ 密钥类型(电子钱包应用)#define DPK0x00/ 消费 Key 类型#define DLK0x01/ 圈存 Key 类型#define DTK0x02/ TAC Key#define DULK0x03/ 圈提 Key 类型#define DUK0x04/ 修改透支 Key 类型#define DAMK0x05/ 应用维护 Key 类型#define DPUK0x06/ P
12、IN 解锁 Key 类型#define DRPK0x07/ PIN 重装 Key 类型#define EXTAUTK0x08/ 外部认证 Key 类型#define INTAUTK0x09/ 内部认证 Key 类型#define CRYPTK0x0A/ 加密 Key 类型#define PIN0x0B/ PIN#define DUKK0x0C/ 联机解扣Key 类?#define STEMP 0x0D/ 临时过程Key 类?/ 密钥类型(借记贷记应用)#define ACUDK0x00/ 应用密文密钥类型#define MACUDK0x01/ 安全报文认证(MAC)密钥类型#define EN
13、CUDK0x02/ 安全报文加密密钥类型#define PINUDK0x03/ PIN1.3.5 应用类型#define DF_PURSE0x00 / PBOC2电子钱包应用#define DF_REFUL0x01 / PBOC2电子钱包扩展应用#define DF_PBOC20x02 / PBOC2借记贷记应用#define DF_VISA0x03 / VISA借记贷记应用#define DF_PKI 0x04 / PKI应用2 文件系统API接口描述2.1 文件创建和删除函数2.1.1 fs_CreateDF功能:创建DF并链接到文件系统中函数接口定义:u16 fs_CreateDF(u1
14、6 fid, u8 flag, u8 aid_length, u8* aid, u8 ext_length, u8* ext)输入:l fid DF文件标识l flag DF标志:0:公共DF,1:与APPLET关联的DFl aid_length 文件名长度l aid DF文件名bufferl ext_length 扩展参数长度l ext 扩展参数bufferl 全局变量d_dfpointer输出:状态码l SW6A80 未创建MF不允许创建其他DF; MF已创建,其他DF的fid不能为3f00;已存在相同fid或aid的DF;l SW6A84 空间不足l SW9000 执行成功l 全局变量d
15、_dfpointer流程图:2.1.2 fs_CreateEF功能:创建EF并链接到文件系统中函数接口定义:u16 fs_CreateEF(u8* ef_header)输入:l ef_header EF文件头信息buffer(19字节)l 全局变量d_dfpointer输出:状态码l SW6A80 已存在相同fid或sfi的EF;l SW6A84 空间不足l SW9000 执行成功l 全局变量d_efpointer流程图:2.1.3 fs_DeleteFile功能:在当前应用下按文件标识删除EF或DF函数接口定义:u16 fs_DeleteFile(u16 fid , u8 type)输入:l
16、 fid EF/DF文件标识l type 文件类型:00(DF),01(EF)l 全局变量d_dfpointer输出:状态码l SW6A82 未找到相同文件标识的DF或EF;l SW9000 执行成功流程图:2.1.4 fs_Initialize功能:设置当前DF。函数接口定义:void fs_Initialize(memref ee_addr)输入:l ee_addr 当前DF地址输出:无流程:给d_dfpointer赋值。2.1.5 fs_IsMFExist功能:判断MF是否创建。函数接口定义:fs_IsMFExist()输入:无输出:l 0 MF已创建;l 1 MF未创建流程:2.2 获
17、取文件信息的函数2.2.1 fs_GetDFid()功能:获取当前DF的文件标识符信息。函数接口定义:u16 fs_GetDFid()输入:无输出:当前DF的文件标识符信息流程:返回d_dfpointer指向的DF的文件标识符2.2.2 fs_GetDFAttrBytes功能:按索引号获取当前DF的专有(扩展)数据信息。函数接口定义:u8 fs_GetDFAttrBytes(u8 index)输入:l index DF的专有(扩展)数据的索引号,从0开始输出:当前DF的专有(扩展)数据信息流程:1. 如果index大于专有数据个数,返回02. 计算当前DF的专有(扩展)数据在文件头中的位置3.
18、 按索引号返回当前DF的专有(扩展)数据信息2.2.3 fs_GetFileAttrByte功能:按索引号获取当前EF的专有(扩展)数据信息。函数接口定义:u8 fs_GetFileAttrByte(u8 index)输入:l index EF的专有(扩展)数据的索引号,从0开始输出:当前EF的专有(扩展)数据信息流程:1. 如果index大于专有数据个数,返回02. 计算当前EF的专有(扩展)数据在文件头中的位置3. 按索引号返回当前EF的专有(扩展)数据信息2.2.4 fs_GetFileType功能:获取当前EF的类型信息。函数接口定义:u8 fs_GetFileType()输入:无输出
19、:当前EF的类型信息l 00 二进制文件l 01 定长记录文件l 02 变长记录文件l 03 循环定长记录文件流程:返回d_efpointer指向的EF的文件类型2.2.5 fs_GetFileSfi功能:获取当前EF的短文件标识符信息。函数接口定义:u8 fs_GetFileSfi()输入:无输出:当前EF的短文件标识符信息(取值范围:131)流程:返回d_efpointer指向的EF的短文件标识符2.2.6 fs_GetFileId功能:获取当前EF的文件标识符信息。函数接口定义:u16 fs_GetFileId()输入:无输出:当前EF的文件标识符信息流程:返回d_efpointer指向
20、的EF的文件标识符2.2.7 fs_GetFileSize功能:获取当前EF的文件大小信息。函数接口定义:u16 fs_GetFileSize()输入:无输出:当前EF占用EE空间大小,只包括文件体。流程:根据文件类型计算当前EF占用EE的大小。2.3 设置文件信息的函数2.3.1 fs_SetDFAttrByte功能:按索引号设置当前DF的专有(扩展)数据。函数接口定义:void fs_SetDFAttrByte(u8 index, u8 value)输入:l index DF的专有(扩展)数据的索引号,从1开始l value 专有(扩展)数据的值输出:无流程:1. 如果index大于专有数
21、据个数或为0,返回02. 计算当前DF的专有(扩展)数据在文件头中的位置3. 修改当前DF的专有(扩展)数据2.3.2 fs_SetFileAttrByte功能:按偏移量设置当前EF的专有(扩展)数据。函数接口定义:void fs_SetFileAttrByte(u8 index, u8 value)输入:l index EF的专有(扩展)数据的索引号,从1开始l value 专有(扩展)数据的值输出:无流程:1. 如果index大于专有数据个数或为0,返回02. 计算当前EF的专有(扩展)数据在文件头中的位置3. 修改当前EF的专有(扩展)数据2.3.3 fs_SetFileHeader功能
22、:函数接口定义:void fs_SetFileHeader(u8 type)2.4 文件查询函数2.4.1 fs_SelectDFByFID功能:在当前应用下根据DF的文件标识查找DF。函数接口定义:u8 fs_SelectDFByFID(u16 fid)输入:l fid DF的文件标识l 全局变量d_dfpointer输出:l 0 找到与文件标识匹配的DF;l 1 未找到与文件标识匹配的DFl 全局变量d_dfpointer流程:2.4.2 fs_SelectDFByAID功能:在当前应用下根据DF的AID查找DF。函数接口定义:u8 fs_SelectDFByAID(u8 aid_leng
23、th, u8* aid)输入:l aid_length DF的文件名长度l aid DF的文件名bufferl 全局变量d_dfpointer输出:l 0 找到与AID匹配的DF;l 1 未找到与AID匹配的DFl 全局变量d_dfpointer流程:2.4.3 fs_SelectEFByFID功能:在当前应用下根据EF的文件标识查找EF。函数接口定义:u8 fs_SelectEFByFID(u16 fid)输入:l fid EF的文件标识l 全局变量d_dfpointer输出:l 0 找到与文件标识匹配的EF;l 1 未找到与文件标识匹配的EFl 全局变量d_efpointer流程:2.4.
24、4 fs_SelectEFBySFI功能:在当前应用下根据EF的短文件标识查找EF。函数接口定义:u8 fs_SelectEFBySFI(u8 sfi)输入:l sfi EF的短文件标识l 全局变量d_dfpointer输出:l 0 找到与短文件标识匹配的EF;l 1 未找到与短文件标识匹配的EFl 全局变量d_efpointer流程:2.4.5 fs_SelectEFByAttrByte功能:在当前应用下根据EF的某一专有(扩展)数据查找EF。函数接口定义:u8 fs_SelectEFByAttrByte(u8 index, u8 value)输入:l index EF的专有(扩展)数据的索
25、引号,从1开始l value 专有(扩展)数据的值l 全局变量d_dfpointer输出:l 0 找到与专有(扩展)数据匹配的EF;l 1 未找到与专有(扩展)数据匹配的EFl 全局变量d_efpointer流程:2.5 EF文件读写函数2.5.1 fs_GetRemainingLength功能:获得当前二进制文件从offset处开始剩余的字节长度。函数接口定义:u16 fs_GetRemainingLength(u16 offset)输入:l offset 偏移量l 全局变量d_efpointer输出:二进制文件从offset处开始剩余的字节长度;流程:1. 如果当前文件不是二进制文件,返回
26、02. 计算二进制文件从offset处开始剩余的字节长度2.5.2 fs_UpdateData功能:从偏移量offset处开始更新二进制文件数据。函数接口定义:u16 fs_UpdateData(u16 offset, u8* new_data, u8 new_data_length)输入:l offset 更新的偏移量l new_data 更新的数据l new_data_length 更新数据的长度l 全局变量d_efpointer输出:状态码l SW6981 文件类型不匹配;l SW6700 更新长度超过文件大小;l SW9000 执行成功流程:1. 如果当前文件不是二进制文件,返回SW6
27、9812. 判断更新长度是否超过文件大小,超过返回SW67003. 二进制文件从offset处开始更新new_data_length长度的数据。返回SW90002.5.3 fs_ReadData功能:从偏移量offset处开始读取二进制文件数据。函数接口定义:u16 fs_ReadData(u16 offset, u8* data_buf, u8 data_length)输入:l offset 更新的偏移量l data_buf 读取的数据存储bufferl data_length 读取数据的长度l 全局变量d_efpointer输出:状态码l SW6981 文件类型不匹配;l SW6700 读
28、取长度超过文件大小;l SW9000 执行成功l data_buf 读取的数据存储buffer流程:1. 如果当前文件不是二进制文件,返回SW69812. 判断读取长度是否超过文件大小,超过返回SW67003. 二进制文件从offset处开始读取data_length长度的数据到data_buf里。返回SW90002.5.4 fs_GetRecordNumber功能:获取当前记录文件的记录数。函数接口定义:u8 fs_GetRecordNumber()输入:全局变量d_efpointer输出:当前记录文件的记录数流程:1. 如果当前文件是二进制文件,返回02. 如果当前文件是定长记录文件,返回
29、定长记录文件记录数(d_filehead.ef.lenlh)3. 如果当前文件是变长记录文件,返回当前记录数总数(d_filehead.ef.origin)4. 如果当前文件是循环定长记录文件,如果记录未满,则返回当前已添加记录数(d_filehead.ef.origin);如果记录已满,则返回循环定长记录文件记录数(d_filehead.ef.lenlh)2.5.5 fs_GetRecordLength功能:获取当前记录文件的记录长度。函数接口定义:u8 fs_GetRecordLength()输入:全局变量d_efpointer输出:当前记录文件的记录长度流程:1. 如果当前文件是二进制文
30、件或变长记录文件,返回02. 如果当前文件是定长记录文件或循环定长记录文件,返回记录长度(d_filehead.ef.lenll)2.5.6 fs_UpdateRecord功能:按模式更新当前记录文件的记录数据。函数接口定义:u16 fs_UpdateRecord(u8 rank, u8 mode, u8* new_record, u8 data_length)输入:l rank 记录号或记录标识l mode 更新模式/ mode = 0 修改与记录标识匹配的第一个实例/ mode = 1 修改与记录标识匹配的最后一个实例/ mode = 2 修改与记录标识匹配的下一个实例/ mode = 3
31、 修改与记录标识匹配的上一个实例/ mode = 4 修改与记录号匹配的记录l new_record 更新的数据bufferl data_length 更新数据的长度l 全局变量d_efpointer输出:状态码l SW6981 文件类型不匹配;l SW6A83 未找到匹配的记录;l SW6700 更新长度超过记录长度;l SW9000 执行成功l 全局变量 d_currecno流程:1. 如果当前文件是二进制文件,返回SW69812. 按模式查找匹配的记录,未找到返回SW6A833. 如果data_length大于记录的长度,则返回SW67004. 更新当前记录的数据,更新d_currecn
32、o为当前记录号,返回SW90002.5.7 fs_ReadRecord功能:按模式读取当前记录文件的记录数据并返回记录长度。函数接口定义:u16 fs_ReadRecord(u8 rank, u8 mode, u8* data_buf, u16* data_length)输入:l rank 记录号或记录标识l mode 读取模式/ mode = 0 读与记录标识匹配的第一个实例rank 为记录标识/ mode = 1 读与记录标识匹配的最后一个实例/ mode = 2 读与记录标识匹配的下一个实例/ mode = 3 读与记录标识匹配的上一个实例/ mode = 4 读与记录号匹配的记录/ m
33、ode = 5 从指定记录号的记录开始读到最后一个记录/ mode = 6 从最后一个记录开始读到指定记录号的记录l 全局变量d_efpointer输出:状态码l SW6981 文件类型不匹配;l SW6A83 未找到匹配的记录;l SW9000 执行成功l data_buf 读取所有的记录数据bufferl data_length 读取所有的记录长度l 全局变量 d_currecno流程:1. 如果当前文件是二进制文件,返回SW69812. 按模式查找匹配的记录,未找到返回SW6A833. 按模式读取记录数据,更新d_currecno为当前记录号,返回SW90002.5.8 fs_Appen
34、dRecord功能:循环记录文件和变长记录文件的添加记录操作。函数接口定义:u16 fs_AppendRecord(u8 data_length, u8* record_data)输入:l data_length 记录长度l record_data 记录数据bufferl 全局变量d_efpointer输出:状态码l SW6981 文件类型不匹配;l SW6A84 超过文件大小;l SW9000 执行成功l 全局变量 d_currecno流程:1. 如果当前文件是二进制文件或定长记录文件,返回SW69812. 计算添加的记录在文件中的偏移量,如果超出文件大小返回SW6A843. 添加记录,更新
35、d_currecno为当前记录号,返回SW90003 文件系统APDU接口描述主要针对金融卡应用设计的。3.1 Create File3.1.1 描述用于创建一个EF/DF文件。3.1.2 定义和设计3.1.2.1 DF分类根据安全机制不同分为三类:1)基于状态机的安全机制的DF(如:电子钱包应用、PKI应用)2)基于安全域和文件控制参数的安全机制的DF(如:借记贷记应用)3)无安全机制的公共DF(只支持7816-4中定义的基本命令)故不同类型的DF,其文件信息就有所不同,具体描述见3.1.3。3.1.2.2 传输密钥8个字节的传输密钥是由工厂在卡片制造时设定的,如用户无特殊要求,则为:FF
36、FF FF FF FF FF FF FF。3.1.2.3 EF文件类型文 件 类 型类型字节文 件 类 型类型字节二进制文件00公钥文件20定长记录文件01证书文件28变长记录文件02银行标准钱包文件38循环定长记录文件03银行标准存折文件40TLV文件04加密公钥文件48数据对象文件0A解密私钥文件50密钥文件11ECCSK58私钥文件18ECCPK60b8 b7 b6 b5 b4b3 b2 b1意义0保留给将来使用x x x x0 0 0 00 0 0 10 0 1 00 0 1 10 1 0 00 1 0 10 1 1 00 1 1 11 0 0 01 0 0 11 0 1 01 0 1
37、 11 1 0 0EF分类- 工作基本文件- 数据对象文件- 密钥文件- 私钥文件- 公钥文件- 证书文件- 签名文件- 银行标准钱包文件- 银行标准存折文件- 加密公钥文件- 解密私钥文件- ECCSK- ECCPKx x x0 0 00 0 10 1 00 1 11 0 0EF结构- 二进制- 定长记录- 变长记录- 循环记录- RUF3.1.2.4 DF文件头中可变部分结构字节属性信息1MF中建立文件和擦除MF权限2-3ATR 文件标识4-5AMD 文件标识6DIR 短文件标识7DF状态8错误计数器9应用类型DF状态:mf.stu mf.stu 的 b7 为1表示 MF 被永久锁定。mf
38、.stu 的 b6-b5 表示创建状态(create status)。 mf.stu 的 b4 为1表示 MF 被临时锁定。 mf.stu 的 b3-b2 RUF。 mf.stu 的 b1 为1表示是 PSAM 卡,为0表示是用户卡。 mf.stu 的 b0 始终为1(DDF)。 df.stu df.stu 的 b7 为1表示应用被永久锁定。 df.stu 的 b6-b5 表示创建状态(create status)。 df.stu 的 b4 为1表示应用被临时锁定。 df.stu 的 b3-b2 是应用解锁错误次数。 df.stu 的 b0 为1表示是 DDF,为0表示是 ADF。错误计数器:
39、b7b6 - APPLICATION UNBLOCK(应用解锁)命令;b5b4 - PIN CHANGE/UNBLOCK(个人密码更改/解锁)命令;b3b2 - SECURE UPDATE BINARY(安全写二进制文件)命令;b1b0 - RELOAD PIN(重装个人密码)命令。支持的应用类型有:(斜体表示暂不支持)应用类型编码应用类型00PBOC电子钱包应用01PBOC电子钱包扩展应用02PBOC借记贷记应用03VISA借记贷记应用04PKI应用F0公用DF3.1.2.5 EF文件头中可变部分字节属性信息1文件子类型2权限13权限24权限3文件子类型:文件子类型编码存储方式对应文件类型编
40、码基本文件00/数据对象文件01变长记录02密钥文件02定长记录01私钥文件03二进制00公钥文件04二进制00证书文件05二进制00银行标准钱包文件07二进制00银行标准存折文件08二进制00加密公钥文件09二进制00解密私钥文件0A二进制00ECCSK文件0B二进制00ECCPK文件0C二进制003.1.3 APDU命令格式描述代 码值CLA 80INS E0P1 00 建立MF 01 建立ADF 02 建立EF 03建立DDFP2 P1=01/03时P2=00/01,否则P2=00Lc 文件信息长度DATA 文件信息Le 不存在3.1.3.1 公共DFl 建立MFMF文件名由用户自定义,
41、Lc的值介于0x18至0x23范围之间。字节文 件 信 息1-6FFFF FFFF FFFF(系统保留)7-8ATR文件FID9FF10DIR文件短文件标识(0表示没有DIR文件)11FF(系统保留)12-19传输密钥20-35MF文件名(5至16字节)短文件标识符指明MF下的应用列表(DIR)文件,该文件是一个变长的记录文件,有效表示为该字节的高三位为000,低5位为短文件的标识符。l 建立DFP2=00时,表示ADF或DDF为公共DF,文件名由用户自定义,Lc的值介于0x12至0x1D范围之间。字节文 件 信 息1-6FFFF FFFF FFFF(系统保留)7-8文件标识符9FF10DIR文件短文件标识(0表示没有DIR文件)11-13FFFFFF(系统保留)14-29DF文件名(5至16字节)3.1.3.2 基于状态机的安全机制DF的文件信息格式P2=01时,表示与APPLET关联的ADF或D