Emv Reader Writer v8.6: 全新计算机EMV软件解决方案

5星 · 超过95%的资源 18 下载量 18 浏览量 更新于2024-11-15 4 收藏 1.05MB RAR 举报
资源摘要信息:"Emv Reader Writer v8.6是基于计算机的EMV软件,主要用于读写EMV卡。EMV卡是一种智能卡标准,广泛应用于银行卡和其他支付卡。EMV代表Europay、MasterCard和Visa,这些公司最初合作开发了这项技术。" 在详细说明这个软件的知识点之前,我们需要理解EMV技术的基础知识。EMV是一种国际标准,用于确保在支付交易中使用芯片卡(如信用卡或借记卡)的安全性。这些卡片内嵌了一个微芯片,用于存储卡信息以及进行加密操作,增加了交易安全性。 1. **EMV卡的读写操作**:Emv Reader Writer v8.6软件可以执行多种任务,包括读取和写入EMV卡中的数据。这包括更新卡片上的信息,比如过期日期、信用额度以及交易记录。 2. **支付系统兼容性**:该软件可能包括与不同支付系统兼容的插件或库文件,比如GlobalPlatform.dll,它支持全球平台(GlobalPlatform)标准,这是一个用于管理智能卡内容和应用程序的安全性框架。这种兼容性使得Emv Reader Writer v8.6能够在多种不同的支付系统中进行操作。 3. **数据库支持**:文件列表中包含的Bin.db文件可能是一个数据库文件,用于存储与EMV卡片交易相关的各种信息。SQLite是一种轻量级的关系数据库管理系统,它包含在文件列表中,可能用于本地存储和管理这些数据。 4. **数据压缩与解压**:zlib1.dll文件表示该软件可能使用zlib库来进行数据压缩与解压。在处理大量卡片数据时,进行压缩可以提高存储和传输效率。 5. **安全性与加密**:Emv Reader Writer v8.6可能会使用到加密技术来保护卡片数据和交易过程的安全。由于文件列表中没有明显指向加密算法的文件,但我们可以合理推断,作为一个处理支付信息的软件,它肯定集成了加密算法来保证数据传输的安全。 6. **软件使用场景**:从标题可以看出,Emv Reader Writer v8.6可能是一个多功能软件,除了基本的读写操作外,还可能具备EMV卡片的测试、调试、维护等功能。 7. **系统兼容性**:文件列表中的.exe文件(Emv Reader Writer v8.6.exe)是可执行程序,而其他列出的DLL文件则表明Emv Reader Writer v8.6软件可能支持在Windows操作系统上运行,因为DLL(动态链接库)文件通常在Windows系统中使用。 8. **更新与维护**:Emv Reader Writer v8.6的版本号8.6表明软件具有版本更新历史。这意味着软件可能定期推出更新,以修复已知问题、改进性能和引入新的功能。 总结来说,Emv Reader Writer v8.6是一个针对EMV智能卡的综合处理软件,提供了卡片的读取、写入、测试和维护等功能。同时,该软件可能还具有与全球支付平台兼容、进行数据存储和加密、以及在特定操作系统上运行的能力。由于它直接涉及金融交易,其安全性是非常重要的考虑因素。
2015-10-23 上传
package br.com.paysmart; import java.util.List; import javax.smartcardio.*; import java.util.*; import java.text.SimpleDateFormat; public class paySmartTest { private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); public static String toHexString(byte[] buf) { char[] chars = new char[2 * buf.length]; for (int i = 0; i < buf.length; ++i) { chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4]; chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F]; } return new String(chars); } public static byte[] hexStringToByteArray(String s) { s = s.replaceAll("\\W+",""); 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; } public static byte[] concat( byte[]...arrays ) { // Determine the length of the result array int totalLength = 0; for (int i = 0; i < arrays.length; i++) { totalLength += arrays[i].length; } // create the result array byte[] result = new byte[totalLength]; // copy the source arrays into the result array int currentIndex = 0; for (int i = 0; i < arrays.length; i++) { System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length); currentIndex += arrays[i].length; } return result; } public static byte[] getCurrentDateAsByteArray( String sFormat ) { SimpleDateFormat sdfDateFormatted = new SimpleDateFormat( sFormat ); Date now = new Date(); String sDate = sdfDateFormatted.format(now); return hexStringToByteArray ( sDate ); } public static byte[] extractTLVFromBuffer( int iTag, byte[] buf ) { //@todo: check size, check 77, etc int i; byte[] bufExtracted = buf; TLV tlvBuf = new TLV( buf, 0 ); if ( iTag <= 0xFF ) { //System.out.println("iTag= "+ iTag + " tlvBuf.type= " + tlvBuf.type + " buf= "+ toHexString( buf ) ); if ( tlvBuf.type == iTag ) { //System.out.println("Found tag = "+ iTag + " " + toHexString( tlvBuf.getValue() ) ); return tlvBuf.getValue(); } else { /* TLV tlvNext = tlvBuf.next; if ( tlvNext != null ) System.out.println( "next = " + toHexString( tlvNext.getDERData() ) ); else System.out.println( "next = NULL" ); while ( tlvNext != null ) { System.out.println("traversing next, looking for "+ iTag ); return extractTLVFromBuffer( iTag, tlvBuf.next.getDERData() ); } */ return extractTLVFromBuffer( iTag, tlvBuf.getValue() ); } } // lookup for iTag else { //@todo double tags /* byte bTag1 = (byte) ( iTag & 0x00FF ); byte bTag2 = (byte) (( iTag & 0xFF00 ) >> 2 ); */ } return buf; } public static String TLVListToString( byte[] bufTLV ) { String sList = ""; int iOffset = 0; int iTLV= 0; System.out.println("[TLVListToString]"); while ( iOffset < bufTLV.length ) { TLV tlvCurrent = new TLV( bufTLV, iOffset ); iTLV++; System.out.println(" TLV[" + iTLV + "].tag = " + tlvCurrent.type ); System.out.println(" TLV[" + iTLV + "].size = " + tlvCurrent.length ); System.out.println(" TLV[" + iTLV + "].value = " + toHexString(tlvCurrent.getValue() ) ); iOffset+= tlvCurrent.getDERData().length; //System.out.println(" TLV["+iTLV+"].DER = " + toHexString(tlvCurrent.getDERData() ) ); System.out.println( iOffset ); System.out.println(); sList += toHexString( tlvCurrent.getValue() ) + "\n"; } return sList; } public static String printAPDU( ResponseAPDU apdu ) { String sAux = apdu.toString() + " data=" + toHexString( apdu.getData() ); return sAux; } public static void main( String[] args ) { try { boolean boolEverythingAsTLV = true; int i; Random RandomNumberGenerator = new Random(); System.out.println("_______________________________________________________"); System.out.println("paySmart EMV Minimalist Terminal v1.0"); System.out.println("www.paySmart.com.br"); System.out.println("_______________________________________________________"); System.out.println(""); for (i=0; i<args.length; i++) System.out.println( "Param " + i + ": "+args[i] ); System.out.println(); if ( args.length < 2 ) { System.out.println(""); System.out.println("usage: paySmartTest #reader AID [Host Port]"); System.out.println(" example1> paySmartTest 0 A0000005551010"); System.out.println(" example2> paySmartTest 1 A000000555E010"); System.out.println(" example3> paySmartTest 1 A0000000041010"); System.out.println(" example4> paySmartTest 1 A0000000041010 10.2.1.1 887"); System.out.println(""); System.out.println("#ERROR# Invalid Params"); System.exit(1); // throw new Exception( "Invalid params" ); } TerminalFactory factory = TerminalFactory.getDefault(); List<CardTerminal> terminals = null; // Display the list of terminals try { terminals = factory.terminals().list(); System.out.println("Smart card readers: "); System.out.println( terminals ); } catch(Exception e) { System.out.println("#ERROR# No readers found"); System.exit(2); //throw new Exception( "No readers found" ); } int iReader=0; // Use the first terminal try { iReader = Integer.parseInt( args[0] ); } catch( Exception e ) { System.out.println("#ERROR# Invalid reader index format '"+args[0]+"'" ); System.exit(3);// throw new Exception( "Invalid reader index '"+args[0]+"'" ); } if ( iReader >= terminals.size() ) { System.out.println("#ERROR# Invalid reader index '"+args[0]+"'. Last valid index is " + (terminals.size()-1) ); System.exit(3); // throw new Exception( "Invalid reader index '"+iReader+"'. Last valid index is "+(terminals.size()-1) ); } CardTerminal terminal = terminals.get( iReader ); // Connect with the card Card card = null; CardChannel channel = null; try { card = terminal.connect("*"); System.out.println(" card: " + card ); channel = card.getBasicChannel(); System.out.println(" ATR=" + toHexString( card.getATR().getBytes() ) ); System.out.println( "" ); } catch( Exception e ) { System.out.println("#ERROR# Cannot connect to card"); System.exit(4); // throw new Exception( "Cannot connect to card" ); } // Send Select Application command //String sAID = "A000000555E010"; // MAIS ACEITO //String sAID = "A0 00 00 05 55 10 10"; String sAID = args[1]; byte[] bufAID = hexStringToByteArray( sAID ); System.out.println( "SELECT (AID = " + toHexString( bufAID ) + ")" ); ResponseAPDU answer = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x04, 0x00, bufAID )); System.out.println( " FCI = "+ toHexString( answer.getData() ) ); System.out.println( "" ); if ( answer.getSW() != 0x9000 ) { System.out.println("#ERROR# Invalid AID '"+sAID+"'" ); System.exit(5); //throw new Exception( "Invalid AID '"+sAID+"'" ); } //Open MEL Application byte[] bufMEL = {(byte) 0x83, 0x00 }; System.out.println( "MEL (MEL = " + toHexString( bufMEL ) + ")" ); answer = channel.transmit( new CommandAPDU(0xBE, 0x12, 0x00, 0x00, bufMEL, 0x00 ) ); System.out.println( " " + printAPDU( answer ) ); //Send GPO byte[] bufPDOL = {(byte) 0x83, 0x00 }; System.out.println( "GPO (PDOL = " + toHexString( bufPDOL ) + ")" ); answer = channel.transmit( new CommandAPDU(0x80, 0xA8, 0x00, 0x00, bufPDOL ) ); System.out.println( " " + printAPDU( answer ) ); byte[] bufAIP = extractTLVFromBuffer( 0x82, answer.getData() ); //byte[] bufAFL = extractTLVFromBuffer( 0x94, answer.getData() ); System.out.println( " AIP = " + toHexString( bufAIP ) ); //System.out.println( " AFL = " + toHexString( bufAIP ) ); System.out.println( "" ); //Send ReadRecord 2 System.out.println( "READ RECORD (SFI=1, REC=2)" ); answer = channel.transmit( new CommandAPDU(0x00, 0xB2, 0x02, 0x0C, 0x3D ) ); //fixed :-( @todo GetResponse System.out.println( printAPDU( answer ) ); byte[] bufExpiryDate = {0x17, 0x01, 0x01}; //Arrays.copyOfRange( answer.getData(), 11, 03 ); System.out.println( " ExpiryDate= " + toHexString( bufExpiryDate ) ); byte [] bufSlice = Arrays.copyOfRange( answer.getData(), 14, answer.getData().length-14 ); byte[] bufPAN = extractTLVFromBuffer( 0x5A, bufSlice ); System.out.println( " PAN = " + toHexString(bufPAN) ); byte[] bufPANSequence = { 0x00 }; // @todo extractTLVFromBuffer( 0x5F34, ... ); System.out.println( " PANSequence = " + toHexString(bufPANSequence) ); System.out.println( "" ); //Send ReadRecord 3 System.out.println( "READ RECORD (SFI=1, REC=3)" ); answer = channel.transmit( new CommandAPDU(0x00, 0xB2, 0x03, 0x0C, 0x43 ) ); //fixed :-( @todo GetResponse System.out.println( printAPDU( answer ) ); byte[] bufSlice2 = Arrays.copyOfRange( answer.getData(), 2, answer.getData().length-2 ); byte[] bufTrack2 = extractTLVFromBuffer( 0x57, bufSlice2 ); System.out.println( " Track2= " + toHexString( bufTrack2 ) ); System.out.println( ); byte[] bufAmountAuthorized = hexStringToByteArray ("00 00 00 00 00 00"); // 9F02 06 ;$0.00 (assuming currency exponent = 2) byte[] bufAmountOther = hexStringToByteArray ("00 00 00 00 00 00"); // 9F03 06 ;$0.00 (assuming currency exponent = 2) byte[] bufTermCountryCode = hexStringToByteArray ("00 76"); // 9F1A 02 ;Brazil byte[] bufTVR = hexStringToByteArray ("00 00 00 08 00"); // 95 05 ;Merchant forced transaction to go online byte[] bufTxCurrencyCode = hexStringToByteArray ("09 86"); // 5F2A 02 ;Brazilian Reals (BRL) byte[] bufTxDate = getCurrentDateAsByteArray("yyMMdd"); // 9A 03 ;04.SET.2014 byte[] bufTxType = hexStringToByteArray ("00"); // 9C 01 ;Goods & services byte[] bufUN = new byte[4]; RandomNumberGenerator.nextBytes(bufUN); // 9F37 04 ;Unpredictable Number System.out.println( " [Transaction Parameters]"); System.out.println( " AmountAuthorized= "+ toHexString( bufAmountAuthorized ) ); System.out.println( " AmountOther= "+ toHexString( bufAmountOther ) ); System.out.println( " TCC= "+ toHexString( bufTermCountryCode ) ); System.out.println( " TVR= "+ toHexString( bufTVR ) ); System.out.println( " TxDate= "+ toHexString( bufTxDate ) ); System.out.println( " TxType= "+ toHexString( bufTxType ) ); System.out.println( " UN= "+ toHexString( bufUN ) ); System.out.println( ""); byte[] bufTxData = concat ( bufAmountAuthorized, bufAmountOther, bufTermCountryCode, bufTVR, bufTxCurrencyCode, bufTxDate, bufTxType, bufUN ); System.out.println( "GenerateAC (TxData= " + toHexString( bufTxData ) + ")" ); answer = channel.transmit( new CommandAPDU( 0x80, 0xAE, 0x40, 0x00, bufTxData ) ); System.out.println( printAPDU( answer ) ); System.out.println( "" ); // get 9F27, 9F36, 9F10, 9F26 byte[] bufResponse = Arrays.copyOfRange( answer.getData(), 2, answer.getData().length ); byte[] bufBit55 = concat( hexStringToByteArray ("82 02"), bufAIP, hexStringToByteArray ("84 07"), bufAID, hexStringToByteArray ("9F1A 02"), bufTermCountryCode, hexStringToByteArray ("95 05"), bufTVR, hexStringToByteArray ("9C 01"), bufTxType, hexStringToByteArray ("9F37 04"), bufUN, bufResponse ); if ( boolEverythingAsTLV ) { bufBit55 = concat( hexStringToByteArray ("5F34 01"), bufPANSequence, hexStringToByteArray ( "5A 08"), bufPAN, //hexStringToByteArray ("5F34 01"), bufPANSequence, hexStringToByteArray ("9F02 06"), bufAmountAuthorized, hexStringToByteArray ("9F03 06"), bufAmountOther, hexStringToByteArray ("5F2A 02"), bufTxCurrencyCode, hexStringToByteArray ( "9A 03"), bufTxDate, bufBit55 ); } System.out.println( "Bit55 = "); System.out.println( toHexString( bufBit55 ) ); System.out.println( ); // Disconnect the card card.disconnect(false); /* // Send to host if ( args.length >= 4 ) { String sHost = args[2]; int iPort = Integer.parseInt( args[3] ); SendISOPacket( sHost, iPort, bufPAN, bufAmountAuthorized, bufAmountOther, bufTxCurrencyCode, bufTxDate, bufExpiryDate, bufTermCountryCode, bufTrack2, bufBit55 ); } */ System.exit(0); } catch(Exception e) { System.out.println( "#ERROR#: " + e.toString() ); System.exit(6); } } }