Python

스마트카드 통신 프로그램 - 2

싸이형아2017.07.26 17:19

이전글: 스마트카드 통신 프로그램 - 1




목표

1. APDU 명령어를 직접 보내고 응답 받는 것을 ScrolledText에 출력


특이사항

1. "Send" 버튼에 연결된 callback 함수에 parameter를 넘겨주기 위해서 lambda 형식을 이용


소스코드

# imports
import tkinter as tk
import tkinter.scrolledtext as tkst
from tkinter import Menu
from tkinter import ttk
from tkinter import messagebox

from smartcard.System import readers
from smartcard.util import toHexString, toBytes


# Click a exit menu
def clickExit():
    win.quit()
    win.destroy()
    exit()

# Click a abount menu
def clickAbout():
    messagebox.showinfo('About', 'About...')

# Click a reset button
def clickReset():
    try:
        for r in readers():
            if r.name == reader_name.get():
                connection = r.createConnection()
                connection.connect()
                stLog.insert(tk.INSERT, 'ATR: ' + toHexString(connection.getATR()) + '\n')
                stLog.see(tk.END)
                return connection
    except:
        messagebox.showinfo('Error', 'Please check a card or readers...')
        return

# Click a send button
def clickSend(connection):
    apdu = toBytes(entryCommand.get())
    response, sw1, sw2 = connection.transmit(apdu)
    #print('response: ', response, ' status words: ', "%x %x" % (sw1, sw2))
    capdu = '< ' + toHexString(apdu) + '\n'
    rapdu = '> ' + toHexString(response) + '\n> {:02X}'.format(sw1) + ' {:02X}'.format(sw2) +'\n'   
    stLog.insert(tk.INSERT, capdu + rapdu)
stLog.see(tk.END)


if __name__ == '__main__':
    connection = None
    win = tk.Tk()                   # Create instance
    win.title('Manager')            # Add a title

    labelReader = ttk.Label(win, text='Reader')
    labelReader.grid(column=0, row=0)

    reader_name = tk.StringVar() # String variable
    comboReader = ttk.Combobox(win, width=30, state='readonly', textvariable=reader_name) # Create a combobox
    comboReader.grid(column=1, row=0)
    comboReader['values'] = readers()
    try:
        comboReader.current(0)
    except:
        pass

    buttonReset = ttk.Button(win, text='Reset...', command=clickReset)  # Create a button
    buttonReset.grid(column=2, row=0)

    stLog = tkst.ScrolledText(win, width=50, height=20, wrap=tk.WORD)   # Create a scrolledtext
    stLog.grid(column=0, row=1, columnspan=3)

    entryCommand = tk.Entry(win, width=40)                              # Create a entry
    entryCommand.grid(column=0, row=2, columnspan=2)
    entryCommand.focus_set()

    buttonCommand = ttk.Button(win, text='Send...', command=lambda: clickSend(connection))  # Create a button
    buttonCommand.grid(column=2, row=2)

    menuBar = Menu(win)                                     # Create a menu
    win.config(menu=menuBar)

    fileMenu = Menu(menuBar, tearoff=0)                     # Create the File Menu
    fileMenu.add_command(label="Exit", command=clickExit)   # Add the "Exit" menu and bind a function
    menuBar.add_cascade(label="File", menu=fileMenu)

    helpMenu = Menu(menuBar, tearoff=0)
    helpMenu.add_command(label="About", command=clickAbout) # Add the "About" menu and bind a function
    menuBar.add_cascade(label="Help", menu=helpMenu)

    connection = clickReset()
    
    win.resizable(0, 0)             # Disable resizing the GUI
    win.mainloop()                  # Start GUI


저작자 표시 비영리 변경 금지
신고

댓글

댓글쓰기 폼

Python

스마트카드 통신 프로그램 - 1

싸이형아2017.07.26 15:01

Python으로 스마트카드 통신 프로그램을 작성해 본다.

이를 위해서는 pyscard가 설치되어 있어야 한다.

pyscard 설치 방법은 "Windows에 pyscard 1.9.5 설치" 포스팅을 참고하기 바란다.


초기 화면


ATR



목표

1. Combobox에 PC/SC 리더기 목록을 표시

2. "Reset" 버튼을 누르면 리셋 후 ATR을 표시



소스코드

# imports
import tkinter as tk
from tkinter import Menu
from tkinter import ttk
from tkinter import messagebox

from smartcard.System import readers
from smartcard.util import toHexString, toBytes

# Click a exit menu
def clickExit():
    win.quit()
    win.destroy()
    exit()

# Click a abount menu
def clickAbout():
    messagebox.showinfo('About', 'About...')

# Click a reset button
def clickReset():
    try:
        for r in readers():
            if r.name == reader_name.get():
                connection = r.createConnection()
                connection.connect()
                messagebox.showinfo('ATR', toHexString(connection.getATR()))
                break
    except:
        messagebox.showinfo('Error', 'Please check a card or readers...')



if __name__ == '__main__':
    win = tk.Tk()                   # Create instance
    win.title('Card Manager')       # Add a title

    reader_label = ttk.Label(win, text='Reader')
    reader_label.grid(column=0, row=0)

    reader_name = tk.StringVar() # String variable
    readerCombo = ttk.Combobox(win, width=30, state='readonly', textvariable=reader_name) # Create a combobox
    readerCombo.grid(column=1, row=0)
    readerCombo['values'] = readers()
    try:
        readerCombo.current(0)
    except:
        pass

    reset = ttk.Button(win, text='Reset...', command=clickReset) # Create a button
    reset.grid(column=2, row=0)

    menuBar = Menu(win)                                     # Create a menu
    win.config(menu=menuBar)

    fileMenu = Menu(menuBar, tearoff=0)                     # Create the File Menu
    fileMenu.add_command(label="Exit", command=clickExit)   # Add the "Exit" menu and bind a function
    menuBar.add_cascade(label="File", menu=fileMenu)

    helpMenu = Menu(menuBar, tearoff=0)
    helpMenu.add_command(label="About", command=clickAbout) # Add the "Exit" menu and bind a function
    menuBar.add_cascade(label="Help", menu=helpMenu)

    win.resizable(0, 0)             # Disable resizing the GUI
    win.mainloop()                  # Start GUI


저작자 표시 비영리 변경 금지
신고

댓글

댓글쓰기 폼

Python

Windows에 pyscard 1.9.5 설치

싸이형아2017.07.25 16:14


Pyscard라는 것은 Python용 스마트카드 패키지이다.

과거 pyscard 1.7.x는 Windows용 설치파일이 배포되었는데, 1.9.x부터 별도의 설치파일은 없고 소스를 직접 받아서 설치해야 한다.


Pyscard 소스 다운로드

https://pyscard.sourceforge.io/index.html#download

접속해 보면 3군데에서 다운로드 받을 수 있으니, 원하는 곳에서 알아서 받도록.


필요 프로그램

소스를 받아서 보면 README에 설치에 필요한 프로그램이 나와 있다. 그런데 pyscard의 버전은 1.7.x로 되어 있다. 아마도 업데이트가 안된듯 싶다.


1. SWIG

http://www.swig.org

이게 뭔가 했더니, C/ C++로 작성된 프로그램을 Javascript, Perl, PHP, Python, Tcl 그리고 Ruby에서 호출해서 사용할 수 있도록 해주는 유틸리티이다. JNI(Java Native Interface)같은 건가 보다. 

이 유틸리티도 좀 알아두면 유용할 듯 싶다.

Windows에서 pyscard가 스마트카드와 통신하기 위해서는 PC/SC(Personal Computer/Smart Card) 라이브러리의 API를 사용해야 할텐데, 이걸 쉽게 하기 위해 C로 먼저 만들고 SWIG를 이용해 python하고 연결한 것으로 보인다.


다운로드 후 압축 해제하고 해당 디렉토리가 환경변수 $PATH에 등록이 되어 있어야 한다.


2. Microsoft Visual C++ Compiler for Python 2.7

http://aka.ms/vcpython27

Python 2.7.x를 사용한다면 설치해야 한다.


3. Visual C++ 2015 Build Tools

http://landinghub.visualstudio.com/visual-cpp-build-tools

Python 3.6.x를 사용한다면 VC 2015 컴파일러가 필요하다.


Build & Install

다운로드 받은 소스를 압축 해제한 다음 콘솔(console)창을 실행시켜 다음과 같이 입력한다.

C:\pyscard-1.9.5>python setup.py build_ext install


그러면 다운로드 받은 소스를 컴파일하고 python이 설치된 디렉토리에 pyscard 패키지를 설치한다.


테스트

C:\>python

Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.

>>> from smartcard.System import readers

>>> from smartcard.util import toHexString

>>> r=readers()

>>> print(r)

['OMNIKEY CardMan 1021 0']

>>> connection = r[0].createConnection()

>>> connection.connect()

>>> SELECT = [0x00, 0xA4, 0x04, 0x00, 0x08, 0xA0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00]

>>> data, sw1, sw2 = connection.transmit( SELECT )

>>> print("%X %X" % (sw1, sw2))

61 5E

>>>

만약 설치가 제대로 되지 않았다면 import에서 부터 에러가 날 것이다.

저작자 표시 비영리 변경 금지
신고

댓글

댓글쓰기 폼