package com.dpkj.modules.cardReader.utils; import com.sun.jna.Library; import com.sun.jna.Native; import lombok.extern.slf4j.Slf4j; @Slf4j public class CardReaderUtil { /** * 获取 多合一读卡器 实例,同时注册 CardReaderSdk 控件。 * * @return CardReaderSdk 实例 * @throws CardReaderRegistrationException 如果注册控件失败,抛出此异常 */ public static CardReaderSdk getCardReaderSDK() throws CardReaderRegistrationException { try { return Native.load("UnPack", CardReaderSdk.class); } catch (UnsatisfiedLinkError e) { log.info("[CardReader][CardReaderUtil.getCardReaderSDK] SDK注册失败 {}", e.getMessage()); throw new CardReaderRegistrationException("Failed to load CardReaderSdk library: ", e); } } public static void convertAndPassStringAsJCharArray(String filePath) { // 将字符串转换为char[] char[] chars = filePath.toCharArray(); } /** * 定义接口映射本地库中的函数。 */ public interface CardReaderSdk extends Library { /** * 连接指定设备与电脑端口,即打开端口 * @param devName 接口名称,如”USB1” * @return >0成功,<=0失败 */ Long ICC_Reader_Open(String devName); /** * 关闭已打开的电脑接口 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @return =0成功,非0失败 */ Long ICC_Reader_Close(Long ReaderHandle); /** * 读写器产生蜂鸣 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param time 蜂鸣时间,以毫秒为单位 * @return =0成功,非0失败 */ Long ICC_PosBeep(Long ReaderHandle, Long time); /** * 获取动态库及设备版本信息 * @return 设备及动态库版本信息 =0成功,非0失败 */ Long ICC_Reader_Libinfo(); /** * 从EEPROM读取数据 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param offset 偏移地址(起始地址) * @param length 要读取的数据的长度 * @return 读取的数据 =0成功,非0失败 */ Long ICC_Reader_ReadEEPROM(Long ReaderHandle, int offset, int length); /** * 往EEPROM写入数据 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param offset 偏移地址(起始地址) * @param length 要写入的数据的长度 * @param buffer 待写入的数据 * @return =0成功,非0失败 */ Long ICC_Reader_WriteEEPROM(Long ReaderHandle, int offset, int length, String buffer); /** * 播放语音(SSSE32.dll暴露函数中未发现该函数,但是文档中有) * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param voiceType 语音类型: * 1、请插卡 * 2、请刷卡 * 3、读卡错误 * 4、请输入密码 * 5、密码错误 * 6、操作成功 * 7、操作超时 * 8、操作失败 * 9、请取回卡 * 10、请重新输入密码 * 11、请再次输入密码 * 12、请输入新密码 * 13、请输入旧密码 * 14、请确认新密码 * @return =0成功,非0失败 */ @Deprecated Long ICC_Reader_DispSound(Long ReaderHandle, String voiceType); /** * 接触 CPU 卡上电复位,返回值数据格式为十六进制字符串 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param ICCSlotNo ICC插槽号 0x01 :大卡座 ; * 0x02 :副卡座 ; * 0x11:SAM1卡座; * 0x12:SAM2卡座; * 0x13:SAM3卡座; * 0x14:SAM4卡座 * 0x3x:非接CPU卡 * @return 上电返回ATR值,数据格式为十六进制字符串 */ Long ICC_Reader_PowerOnHEX(Long ReaderHandle, String ICCSlotNo); /** * CPU 卡下电 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param ICCSlotNo ICC插槽号 0x01 :大卡座 ; * 0x02 :副卡座 ; * 0x11:SAM1卡座; * 0x12:SAM2卡座; * 0x13:SAM3卡座; * 0x14:SAM4卡座 * 0x3x:非接CPU卡 * @return =0成功,非0失败 */ Long ICC_Reader_PowerOff(Long ReaderHandle, String ICCSlotNo); /** * 获取卡座状态 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param ICCSlotNo ICC插槽号 0x01 :大卡座 ; * 0x02 :副卡座 ; * 0x11:SAM1卡座; * 0x12:SAM2卡座; * 0x13:SAM3卡座; * 0x14:SAM4卡座 * 0x3x:非接CPU卡 * @return = 0 表示卡座有卡,其他见状态码 */ Long ICC_Reader_GetStatus(Long ReaderHandle, String ICCSlotNo); /** * 接触 CPU 卡执行APDU命令 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param ICCSlotNo ICC插槽号 0x01 :大卡座 ; * 0x02 :副卡座 ; * 0x11:SAM1卡座; * 0x12:SAM2卡座; * 0x13:SAM3卡座; * 0x14:SAM4卡座 * 0x3x:非接CPU卡 * @param CommandAPDU APDU命令数据,以十六进制字符串形式输入 * @return 大于 0 表示执行成功,其值为 Response_APDU 的数据长度.否则表示执行失败 */ Long ICC_Reader_ApplicationHEX(Long ReaderHandle, String ICCSlotNo, String CommandAPDU); /** * 4442卡片上电,数据以十六进制字符串输出 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @return 返回卡片上电信息 = 0 表示成功,非0失败 */ Long ICC_Reader_4428_PowerOnHEX(Long ReaderHandle); /** * 4442卡片下电 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @return = 0 表示成功,非0失败 */ Long ICC_Reader_4442_PowerOff(Long ReaderHandle); /** * 读取4442卡的指定字段内容,以十六进制字符串输出 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param offset 起始地址,需小于256 * @param len 数据长度,offset+len需小于256 * @return 返回卡片读取信息 = 0 表示成功,非0失败 */ Long ICC_Reader_4428_ReadHEX(Long ReaderHandle, int offset, int len); /** * 写 4442 卡的指定字段内容,以十六进制字符串输入参数 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param offset 起始地址,需小于256 * @param len 数据长度,offset+len需小于256 * @param data 待写入卡片数据 * @return 返回卡片读取信息 = 0 表示成功,非0失败 */ Long ICC_Reader_4428_WriteHEX(Long ReaderHandle, int offset, int len, String data); /** * 4442卡认证密钥 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param keyHex 卡密钥 * @return = 0 表示成功,非0失败 */ Long ICC_Reader_4442_Verify(Long ReaderHandle, String keyHex); /** ----- 非接触操作函数 -------------- */ /** * 查找天线磁场区域内有无卡,只有卡片上电后才能查找到 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @return = 0 表示成功,非0失败 */ Long PICC_Reader_Request(Long ReaderHandle); /** * 天线操作 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param flag 00-关场强 01-开场强 * @return = 0 表示成功,非0失败 */ Long PICC_Reader_RFControl(Long ReaderHandle, String flag); /** --------------- 非接 CPU 卡操作函数 ------------ */ /** * 非接TypeA CPU卡上电复位,输出十六进制字符串(SSSE32.dll暴露函数中未发现该函数,但是文档中有) * @param ReaderHandle ICCReaderOpen函数所返回的值 * @return 输出上电成功返回的卡片复位信息(ATS) 返回ATS长度,大于0 表示成功,其他失败 */ @Deprecated Long PICC_Reader_PowerOnTypeAHEX(Long ReaderHandle); /** * 非接TypeB CPU卡上电复位,输出十六进制字符串(SSSE32.dll暴露函数中未发现该函数,但是文档中有) * @param ReaderHandle ICCReaderOpen函数所返回的值 * @return 输出上电成功返回的卡片复位信息(ATS) 返回ATS长度,大于0 表示成功,其他失败 */ @Deprecated Long PICC_Reader_PowerOnTypeBHEX(Long ReaderHandle); /** * 非接触 CPU 卡执行APDU命令,命令以十六进制字符串传输(SSSE32.dll暴露函数中未发现该函数,但是文档中有) * @param ReaderHandle ICCReaderOpen函数所返回的值 * @param CommandAPDU APDU命令数据,以十六进制字符串形式输入 * @return APDU命令执行后,响应的数据,返回数据为十六进制字符串 * 大于 0 表示执行成功,其值为 Response_APDU 的数据长度.否则表示执行失败 */ @Deprecated Long PICC_Reader_ApplicationHEX(Long ReaderHandle, String CommandAPDU); /** ---------------- 二代证/外国人居留证/港澳台居住证 --------------- */ /** * 读取身份证物理ID号 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @return 返回身份证物理ID信息 = 0 表示成功,非0失败 */ Long PICC_Reader_Read_CardID(Long ReaderHandle); /** * 读取身份证物理ID号 * @param ReaderHandle ICCReaderOpen函数所返回的值 * @return 返回错误信息 = 0 表示成功,非0失败 */ Long PICC_Reader_ReadIDCard(Long ReaderHandle); /** 以下函数须在 “PICCReaderReadIDCard” 函数执行成功之后调用,否则获取不到有效信息 */ /** * 获取证件类型 * @return * 0:居民身份证 * 1:外国人永久居留证 * 2:港澳台居民居住证 * 4:新外国人永久居留证 */ Integer GetCardType(); /** * 姓名(类型为 1 时表示:外国人中文姓名) */ Integer GetName(); /** * 性别 */ Integer GetSex(); /** * 民族 */ Integer GetNation(); /** * 出生日期 */ Integer GetBirth(); /** * 住址 */ Integer GetAddress(); /** * 公民身份证号码(类型为 1时表示:外国人居留证号码) */ Integer GetCertNo(); /** * 签发机关 */ Integer GetDepartemt(); /** * 有效起始日期 */ Integer GetEffectDate(); /** * 有效截止日期 */ Integer GetExpireDate(); /** * bmp 格式照片数据 */ Integer GetBmpFileData(); /** * 生成照片 * TODO 入参参考文中3.4.1 */ Integer GetBmpFile(); /** * 是否含存在指纹信息:存在时返回 512 或者 1024 * 不存在时返回 0 */ Integer IsFingerExist(); /** * 获取指纹数据:成功时返回获取到的字节长度 */ Integer GetFingerprint(); /** * 外国人英文姓名 */ Integer GetEnName(); /** * 外国人国籍代码,符合GB/T2659-2000规定 */ Integer GetNationalityCode(); /** * 港澳台通行证号码 */ Integer GetTXZHM(); /** * 港澳台通行证签发次数 */ Integer GetTXZQFCS(); /** * 外国人换证次数 */ Integer GetHZCS(); /** ------------ 社保卡 ---------*/ /** * 选择社保卡社会保障系统环境后,通过 PSAM 卡对社保卡进行内部认证,通过后将卡内的基本信息读出返回。 * @param iType 操作卡的类型 * 1-接触式操作卡; * 2-非接触式操作卡; * 3-自动寻卡,接触式操作卡优先; * 4-自动寻卡,非接触式操作卡优先 * @return */ Long iReadCardBas(Integer iType); /** * 基于加密机的读基本信息(步骤一) * 选择社会保障系统环境后,返回内部认证和外部认证所需信息。 * @param iType 操作卡的类型 * 1-接触式操作卡; * 2-非接触式操作卡; * 3-自动寻卡,接触式操作卡优先; * 4-自动寻卡,非接触式操作卡优先 * @return */ Long iReadCardBas_HSM_Step1(Integer iType); /** * 基于加密机的读基本信息(步骤二) * 根据加密机返回的内部认证和外部认证结果数据对社保卡进行内部认证和外部认证,通过后将卡内的基本信息读出返回。 * @param pKey 加密机返回的内部认证和外部认证结果数据,依次为:内部认证结果数据 * (即内部认证鉴别数据(16 位)和内部认证鉴别所需的原始信息(16 位)拼接组 * 成)、外部认证结果数据(即外部认证鉴别数据(16 位)和外部认证鉴别所需的 * 原始信息(16 位)拼接组成)。各数据项之间以“|”分割,且最后一个数据项以“|”结尾。 * @return */ Long iReadCardBas_HSM_Step2(String pKey); } /** * 定义自定义异常类,用于表示注册控件时发生的错误 */ public static class CardReaderRegistrationException extends Exception { public CardReaderRegistrationException(String message) { super(message); } public CardReaderRegistrationException(String message, Throwable cause) { super(message, cause); } } }