Difference between revisions of "JavaCard"
Jump to navigation
Jump to search
Line 23: | Line 23: | ||
card_disconnect |
card_disconnect |
||
release_context |
release_context |
||
+ | </pre> |
||
+ | |||
+ | ===Application Java pour lister quelques informations sur la carte=== |
||
+ | <pre> |
||
+ | package fr.imag.javacard; |
||
+ | |||
+ | import javax.smartcardio.*; |
||
+ | import java.util.*; |
||
+ | |||
+ | public class Main { |
||
+ | static class Util { |
||
+ | static final String HEXES = "0123456789ABCDEF"; |
||
+ | |||
+ | public static String getHex(byte[] raw) { |
||
+ | if (raw == null) { |
||
+ | return null; |
||
+ | } |
||
+ | final StringBuilder hex = new StringBuilder(2 * raw.length); |
||
+ | for (final byte b : raw) { |
||
+ | hex.append(HEXES.charAt((b & 0xF0) >> 4)) |
||
+ | .append(HEXES.charAt((b & 0x0F))); |
||
+ | } |
||
+ | return hex.toString(); |
||
+ | } |
||
+ | } |
||
+ | |||
+ | private static byte[] appletAID = {0x55, 0x6E, 0x69, 0x76, 0x2E, 0x55, 0x4A, 0x46}; |
||
+ | private final static byte INS_SELECT = (byte) 0xA4; |
||
+ | private final static byte INS_GETDATA = (byte) 0xCA; |
||
+ | |||
+ | static class Command { |
||
+ | String description; |
||
+ | |||
+ | Command(String description) { |
||
+ | this.description = description; |
||
+ | } |
||
+ | } |
||
+ | |||
+ | private static final Map<Integer, Command> COMMAND_MAP = |
||
+ | Collections.unmodifiableMap(new HashMap<Integer, Command>() {{ |
||
+ | put(1, new Command("ID(?)")); |
||
+ | put(2, new Command("Version(?)")); |
||
+ | put(3, new Command("(?)")); |
||
+ | put(4, new Command("INE")); |
||
+ | put(5, new Command("Creation(?)")); |
||
+ | put(6, new Command("Update(?)")); |
||
+ | }}); |
||
+ | |||
+ | public static CardTerminal selectCardTerminal() throws Exception { |
||
+ | Scanner in = new Scanner(System.in); |
||
+ | TerminalFactory tf = TerminalFactory.getDefault(); |
||
+ | List<CardTerminal> ctlist = null; |
||
+ | ctlist = tf.terminals().list(); |
||
+ | if (ctlist.size() == 0) { |
||
+ | throw new Exception("No reader present"); |
||
+ | } |
||
+ | if (ctlist.size() == 1) { |
||
+ | return ctlist.get(0); |
||
+ | } |
||
+ | |||
+ | int index = 0; |
||
+ | do { |
||
+ | |||
+ | System.out.println("Readers:"); |
||
+ | System.out.println("============================================"); |
||
+ | for (CardTerminal ct : ctlist) { |
||
+ | System.out.println(index++ + ": " + ct.getName()); |
||
+ | } |
||
+ | System.out.print("Select a reader:"); |
||
+ | index = in.nextInt(); |
||
+ | } while (index < 0 || index >= ctlist.size()); |
||
+ | |||
+ | return ctlist.get(index); |
||
+ | } |
||
+ | |||
+ | public static void selectApplication(CardChannel cc) throws Exception { |
||
+ | System.out.println("Selecting \"Univ.UJF\" application"); |
||
+ | |||
+ | CommandAPDU apdu = new CommandAPDU( |
||
+ | 0x00, INS_SELECT, |
||
+ | 0x4, 0x0, |
||
+ | appletAID); |
||
+ | |||
+ | ResponseAPDU rapdu = cc.transmit(apdu); |
||
+ | if (rapdu.getSW() != 0x9000) { |
||
+ | throw new Exception("Can't select \"Univ.UJF\" application: " |
||
+ | + Integer.toHexString(rapdu.getSW())); |
||
+ | } |
||
+ | |||
+ | } |
||
+ | |||
+ | public static void main(String[] args) { |
||
+ | try { |
||
+ | CardTerminal ct = selectCardTerminal(); |
||
+ | Card c = ct.connect("T=0"); |
||
+ | ATR atr = c.getATR(); |
||
+ | System.out.println("ATR : " + Util.getHex(atr.getBytes())); |
||
+ | CardChannel cc = c.getBasicChannel(); |
||
+ | |||
+ | selectApplication(cc); |
||
+ | |||
+ | for (int id : COMMAND_MAP.keySet()) { |
||
+ | Command cmd = COMMAND_MAP.get(id); |
||
+ | CommandAPDU apdu = new CommandAPDU( |
||
+ | 0x00, INS_GETDATA, |
||
+ | (byte) id, 0x00, new byte[]{0x01}); |
||
+ | |||
+ | ResponseAPDU rapdu = cc.transmit(apdu); |
||
+ | if (rapdu.getSW() != 0x9000) { |
||
+ | throw new Exception("Can't get data (" + id + "): " |
||
+ | + Integer.toHexString(rapdu.getSW())); |
||
+ | } |
||
+ | System.out.println(cmd.description + ":" |
||
+ | + new String(rapdu.getData())); |
||
+ | } |
||
+ | } catch (Exception e) { |
||
+ | |||
+ | e.printStackTrace(); |
||
+ | } |
||
+ | } |
||
+ | } |
||
</pre> |
</pre> |
Revision as of 23:28, 20 March 2011
JavaCard est un canevas d’exécution d'application pour carte à puce développé en Java.
Les outils
Global Platform
Global Platform est un standard permettant l'installation de cardapplets.
Carte étudiante (ancienne génération)
Script pour lister les card applets
mode_211 gemXpressoPro enable_trace establish_context card_connect select -AID a000000018434d open_sc -security 3 -keyind 0 -keyver 0 -key 47454d5850524553534f53414d504c45 // Open secure channel get_status -element 20 card_disconnect release_context
Application Java pour lister quelques informations sur la carte
package fr.imag.javacard; import javax.smartcardio.*; import java.util.*; public class Main { static class Util { static final String HEXES = "0123456789ABCDEF"; public static String getHex(byte[] raw) { if (raw == null) { return null; } final StringBuilder hex = new StringBuilder(2 * raw.length); for (final byte b : raw) { hex.append(HEXES.charAt((b & 0xF0) >> 4)) .append(HEXES.charAt((b & 0x0F))); } return hex.toString(); } } private static byte[] appletAID = {0x55, 0x6E, 0x69, 0x76, 0x2E, 0x55, 0x4A, 0x46}; private final static byte INS_SELECT = (byte) 0xA4; private final static byte INS_GETDATA = (byte) 0xCA; static class Command { String description; Command(String description) { this.description = description; } } private static final Map<Integer, Command> COMMAND_MAP = Collections.unmodifiableMap(new HashMap<Integer, Command>() {{ put(1, new Command("ID(?)")); put(2, new Command("Version(?)")); put(3, new Command("(?)")); put(4, new Command("INE")); put(5, new Command("Creation(?)")); put(6, new Command("Update(?)")); }}); public static CardTerminal selectCardTerminal() throws Exception { Scanner in = new Scanner(System.in); TerminalFactory tf = TerminalFactory.getDefault(); List<CardTerminal> ctlist = null; ctlist = tf.terminals().list(); if (ctlist.size() == 0) { throw new Exception("No reader present"); } if (ctlist.size() == 1) { return ctlist.get(0); } int index = 0; do { System.out.println("Readers:"); System.out.println("============================================"); for (CardTerminal ct : ctlist) { System.out.println(index++ + ": " + ct.getName()); } System.out.print("Select a reader:"); index = in.nextInt(); } while (index < 0 || index >= ctlist.size()); return ctlist.get(index); } public static void selectApplication(CardChannel cc) throws Exception { System.out.println("Selecting \"Univ.UJF\" application"); CommandAPDU apdu = new CommandAPDU( 0x00, INS_SELECT, 0x4, 0x0, appletAID); ResponseAPDU rapdu = cc.transmit(apdu); if (rapdu.getSW() != 0x9000) { throw new Exception("Can't select \"Univ.UJF\" application: " + Integer.toHexString(rapdu.getSW())); } } public static void main(String[] args) { try { CardTerminal ct = selectCardTerminal(); Card c = ct.connect("T=0"); ATR atr = c.getATR(); System.out.println("ATR : " + Util.getHex(atr.getBytes())); CardChannel cc = c.getBasicChannel(); selectApplication(cc); for (int id : COMMAND_MAP.keySet()) { Command cmd = COMMAND_MAP.get(id); CommandAPDU apdu = new CommandAPDU( 0x00, INS_GETDATA, (byte) id, 0x00, new byte[]{0x01}); ResponseAPDU rapdu = cc.transmit(apdu); if (rapdu.getSW() != 0x9000) { throw new Exception("Can't get data (" + id + "): " + Integer.toHexString(rapdu.getSW())); } System.out.println(cmd.description + ":" + new String(rapdu.getData())); } } catch (Exception e) { e.printStackTrace(); } } }