Я новичок в технологии смарт-карт. Я хочу читать файл с смарт-карты. Я использую javax.smartcardio для чтения значения. Я разработал код для подключения системы к карте (это хорошо работает). У меня есть карта ATR и другие детали. Но не получить правильную помощь для команды APDU для связи со смарт-картой. Застрял в команде APDU.Как читать файл с смарт-карты с помощью java
ответ
Прежде всего:
"Не" все Java-карты имеют MF
, DF
EF
и внутри! Эти слова означают Главный файл, Выделенный файл и Элементарный файл на заказ. Они являются компонентами системного файла, определяемого ISO7816 для смарт-карты (refer to part 4 of ISO7816), поэтому ваша карта может быть или не иметь эту файловую систему.
Типичная ява карта имеет хранилище, которое вы можете установить апплеты в нем (после успешной аутентификации наверняка) и зарегистрировать имя вашего апплета (мы называем его AID, что означает Applet IDentifier и это 5 до 16-байтной шестнадцатеричной последовательности) в таблице реестра карты (таблица загруженных/установленных апплетов и пакетов, которые также содержат жизненные циклы и привилегии) - read Global Platform Card Spec).
И потом:
Пусть Предположим, что у вас есть смарт-карты, установленной в вашем кард-ридер, который подключен к компьютеру. У вас есть разные опции для связи между вашим компьютером и картой.
1-Вы можете использовать имеющиеся инструменты, такие как инструмент вашего читателя (почти все читатели имеют один инструмент), PyAPDUTool и т.д.
2-Вы можете использовать Javax.smartcardio
библиотеку для написания программы Java для связи со смарт-картами :
import java.util.List;
import java.util.Scanner;
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
import javax.smartcardio.TerminalFactory;
import javax.xml.bind.DatatypeConverter;
public class TestPCSC {
public static void main(String[] args) throws CardException {
TerminalFactory tf = TerminalFactory.getDefault();
List< CardTerminal> terminals = tf.terminals().list();
System.out.println("Available Readers:");
System.out.println(terminals + "\n");
Scanner scanner = new Scanner(System.in);
System.out.print("Which reader do you want to send your commands to? (0 or 1 or ...): ");
String input = scanner.nextLine();
int readerNum = Integer.parseInt(input);
CardTerminal cardTerminal = (CardTerminal) terminals.get(readerNum);
Card connection = cardTerminal.connect("DIRECT");
CardChannel cardChannel = connection.getBasicChannel();
System.out.println("Write your commands in Hex form, without '0x' or Space charaters.");
System.out.println("\n---------------------------------------------------");
System.out.println("Pseudo-APDU Mode:");
System.out.println("---------------------------------------------------");
while (true) {
System.out.println("Pseudo-APDU command: (Enter 0 to send APDU command)");
String cmd = scanner.nextLine();
if (cmd.equals("0")) {
break;
}
System.out.println("Command : " + cmd);
byte[] cmdArray = hexStringToByteArray(cmd);
byte[] resp = connection.transmitControlCommand(CONTROL_CODE(), cmdArray);
String hex = DatatypeConverter.printHexBinary(resp);
System.out.println("Response : " + hex + "\n");
}
System.out.println("\n---------------------------------------------------");
System.out.println("APDU Mode:");
System.out.println("---------------------------------------------------");
while (true) {
System.out.println("APDU command: (Enter 0 to exit)");
String cmd = scanner.nextLine();
if (cmd.equals("0")) {
break;
}
System.out.println("Command : " + cmd);
byte[] cmdArray = hexStringToByteArray(cmd);
ResponseAPDU resp = cardChannel.transmit(new CommandAPDU(cmdArray));
byte[] respB = resp.getBytes();
String hex = DatatypeConverter.printHexBinary(respB);
System.out.println("Response : " + hex + "\n");
}
connection.disconnect(true);
}
public static int CONTROL_CODE() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName.indexOf("windows") > -1) {
/* Value used by both MS' CCID driver and SpringCard's CCID driver */
return (0x31 << 16 | 3500 << 2);
} else {
/* Value used by PCSC-Lite */
return 0x42000000 + 1;
}
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len/2];
for (int i = 0; i < len; i += 2) {
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}
3- Вы можете использовать PySCard
библиотеку, чтобы написать программу на Python, чтобы общаться со смарт-картами:
#Importing required modules.
import sys
import time
#--- You may need to change the following "line" based on your pyScard library installation path
sys.path.append("D:\\PythonX\\Lib\\site-packages")
from smartcard.scard import *
import smartcard.util
from smartcard.System import readers
#---This is the list of commands that we want to send device
cmds =[[,0xFF,0x69,0x44,0x42,0x05,0x68,0x92,0x00,0x04,0x00],]
#--- Let's to make a connection to the card reader
r=readers()
print "Available Readers :",r
print
target_reader = input("--- Select Reader (0, 1 , ...): ")
print
while(True):
try:
print "Using :",r[target_reader]
reader = r[target_reader]
connection=reader.createConnection()
connection.connect()
break
except:
print "--- Exception occured! (Wrong reader or No card present)"
ans = raw_input("--- Try again? (0:Exit/1:Again/2:Change Reader)")
if int(ans)==0:
exit()
elif int(ans)==2:
target_reader = input("Select Reader (0, 1 , ...): ")
#--- An struct for APDU responses consist of Data, SW1 and SW2
class stru:
def __init__(self):
self.data = list()
self.sw1 = 0
self.sw2 = 0
resp = stru()
def send(cmds):
for cmd in cmds:
#--- Following 5 line added to have a good format of command in the output.
temp = stru() ;
temp.data[:]=cmd[:]
temp.sw1=12
temp.sw2=32
modifyFormat(temp)
print "req: ", temp.data
resp.data,resp.sw1,resp.sw2 = connection.transmit(cmd)
modifyFormat(resp)
printResponse(resp)
def modifyFormat(resp):
resp.sw1=hex(resp.sw1)
resp.sw2=hex(resp.sw2)
if (len(resp.sw2)<4):
resp.sw2=resp.sw2[0:2]+'0'+resp.sw2[2]
for i in range(0,len(resp.data)):
resp.data[i]=hex(resp.data[i])
if (len(resp.data[i])<4):
resp.data[i]=resp.data[i][0:2]+'0'+resp.data[i][2]
def printResponse(resp):
print "res: ", resp.data,resp.sw1,resp.sw2
send(cmds)
connection.disconnect()
4 Вы можете использовать библиотеку WinSCard
, чтобы написать свою программу на C++ /. Net (не уверен) для общения с смарт-картами.
Выше программы представляют собой примеры программ для отправки команд APDU на смарт-карты. Но команды themselve зависят от вашей карты и апплетов, которые [ваши] установлены на ней.
Например, допустим, что вы пишете апплет с AID = 01 02 03 04 05 00
, который возвращает 11 22 33 44 55
, когда он принимает 00 00 00 00 00
в качестве команды APDU. Что вам нужно сделать, чтобы получить этот ответ (т.е. 11 22 33 44 55
), как показано ниже:
- Отправить ВЫБРАТЬ Команда APDU с вами апплета AID в своей области данных.
- Отправка
00 00 00 00 00
на ваш апплет. - Ваш ответ апплета на вышеуказанную команду с ожидаемым ответом.
Если ваша карта была внедрена системным файлом ISO7816, для их выбора требуется идентификатор файлов. но сами команды определены в ISO7816-P4.
Даже если на ваших картах не был установлен системный файл ISO7816, вы можете написать апплет для работы как системный файл с ISO7816-P, реализованный с помощью смарт-карты (в любом случае это нелегко).
Как ID MF 3F00
всегда, пытаясь выбрать этот файл, покажет вам, если ваша карта внедрила системный файл или нет.
Как правило, когда ваша карта включена, обязательная сущность на карточке с именем Card Manager получает ваши команды APDU. Используя команду SELECT APDU, вы запрашиваете диспетчер карт отправлять следующие входящие команды в выбранный APPLET
На рынке есть различные виды смарт-карт. Каждая из них использует другую структуру для хранения данных внутри. Файловая структура определяется в I SO 7816-4: Организация, безопасность и команды для обмена
Вы можете увидеть link1 и Link2 для больше о смарт файловой структуре карты.
Это выбор лица персонализации карты, независимо от того, используют ли они эту файловую структуру или нет для хранения данных внутри чипа. Индийский стандарт SCOSTA полностью соответствует стандарту ISO 7816, это означает, что любой продукт, который SCOSTA complient будет использовать структуру, определенную в ISO 7816-4 (MF, DF, EF).
Здесь вы должны знать структуру карты перед отправкой любой команды на нее. Подобно Select MF -> Select DF -> Select EF -> Read Record Command.
В случае карты java (смарт-карты) не всегда создается структура файлов, предназначенная для хранения данных, могут использоваться массивы [i.e. Постоянная память] и присваивать значения во время операций. Это значение соответствует сроку службы смарт-карт. Хотите получить значение, просто отправьте соответствующую определенную команду, и карта вернет вам значение из массива. вот и все.
Это означает, что мы можем сказать, что все смарт-карты не следует правилу структуры файла
Чтобы прочитать любые смарт-карт есть некоторые заранее определенные правила, если карта является структурой мудрой, мы должны знать структуру в противном случае мы может получить Error status word.
Если вы говорите о команде, это также определено Here -Smart Card Command Rules, вы можете прочитать здесь, чтобы улучшить свои знания о командах смарт-карт, чтобы вы могли отправить правильную команду.
But not getting proper help for APDU command for communication with Smart card. Stuck in APDU command.
Здесь вы должны узнать больше о смарт-карте, которую вы используете, перед отправкой любой команды на нее. Хорошо проверить командный ответ, чтобы проверить точный вопрос. javax.smartcardio - очень хороший API для связи со смарт-картой, также есть любой другой пример shared, который поможет вам написать код для доступа к любой смарт-карте.
Надеюсь, зная глубокую деталь смарт-карты, которую вы используете, и как только вы создадите соответствующую команду, вы не получите никаких ошибок. Надеюсь, поможет.
Что вы наделали? Чего вы ожидали? Что произошло вместо этого? – Henry
@Henry. Выполнено: подключите смарт к системе. Ожидайте: хотите общаться со смарт-картой. Happened: Ошибка Throe, параметры p1 и p2 неверны. Когда я передаю команду на смарт-карту. У меня больше нет знаний о команде Апду. –
Я не думаю, что вы используете библиотеку java-карт. Вероятно, вы используете javax.smarcardio. Это библиотека JAVA. Для получения дополнительной информации о том, как читать вашу карточку, прочитайте документацию производителя смарт-карт ISO7816-4 и thee –