All Articles

Linux 환경의 Python에서 Windows DLL 사용하기

Python에서는 DLL이나 공유 라이브러리를 불러오기 위한 ctypes라는 표준 라이브러리를 제공합니다. 단, Windows 환경에서는 Linux shared object 파일을 불러오지 못하고, Linux 환경에서는 Windows DLL 파일을 불러오지 못하는 한계가 있습니다. 기본적으로는요.

Linux에는 Windows EXE 파일을 실행시킬 수 있는 Wine이 있습니다. zugbruecke 라는 Python 라이브러리는 이를 이용하여 Linux에서도 Windows DLL를 로드해 사용할 수 있게 해 줍니다.


국세청 홈택스 자료실의 [550. 변환방식 전자신고 파일의 암호화 조치 안내(2018.11.14.부터 적용)] 글의 첨부2_세무자료 암호화 적용 API.zip 파일을 다운로드 받아 아래의 DLL 파일을 복사합니다.

  • singo_encryption_api/_bin/enconly_stdcall/fcrypt_es.dll
  • singo_encryption_api/_bin/enconly_stdcall/MagicCrypto.dll

Dockerfile 입니다. 의존성으로 Wine를 설치합니다.

FROM python:3.8.2

WORKDIR /app
COPY MagicCrypto.dll fcrypt_es.dll ./

RUN pip install zugbruecke
RUN sed -i -E 's/deb.debian.org/mirror.kakao.com/' /etc/apt/sources.list 
RUN dpkg --add-architecture i386 && apt update && apt install -y wine wine32 && rm -rf /var/lib/apt/lists/*

# 최초 로딩 시 어디선가 파일을 다운로드 받는다. 미리 받아놓으면 이후 실행속도가 빨라짐.
RUN python -c 'import zugbruecke; zugbruecke.windll.LoadLibrary("fcrypt_es.dll")'

이제 Python으로 암호화가 잘 되는지 테스트 해 봅시다. 테스트입니다! 텍스트를 euc-kr 인코딩으로 만들고 국세청 암호화 모듈을 실행시켜 봅니다. 이 때, stdcall은 ctypes.windll.LoadLibrary 함수를, cdecl은 ctypes.cdll.LoadLibrary 함수를 사용하여 로드하면 됩니다.

In [1]: import zugbruecke as ctypes
   ...: import zugbruecke.wintypes as wintypes

In [2]: fcrypt_es = ctypes.windll.LoadLibrary('fcrypt_es.dll')  # stdcall: windll, cdecl: cdll
   ...: encrypt_file = fcrypt_es.DSFC_EncryptFile
   ...: encrypt_file.argtypes = (  # 필수는 아님
   ...:     wintypes.HWND,
   ...:     ctypes.c_char_p,
   ...:     ctypes.c_char_p,
   ...:     ctypes.c_char_p,
   ...:     wintypes.UINT,
   ...: )

In [3]: open('/app/test.txt', 'wb').write('테스트입니다!'.encode('euc-kr'))
Out[3]: 13

In [4]: encrypt_file(0, b'/app/test.txt', b'/app/test_encrypted.txt', b'12345678', 1)
Out[4]: 0

잘 됩니다! 국세청 홈택스 자료실의 [550. 변환방식 전자신고 파일의 암호화 조치 안내(2018.11.14.부터 적용)] 글의 첨부3_세무자료 암호화 뷰어 프로그램.zip 를 내려받아 정상적으로 복호화가 가능한지 테스트 해 보았습니다.

Linux에서 Wine으로 암호화한 파일을 Windows에서 복호화가 정상적으로 되는 것을 확인할 수 있습니다.