[windows] pysqlcipher3 사용하기
2024년 10월 18일
pysqlcipher3 #
분석을 하다보면 sqlcipher로 암호화된 데이터베이스를 자주 볼 수 있다.
처음 복호화에 사용할땐 ubuntu를 깔아서 설치했는데 문제 없이 사용할 수 있었지만, 다시 환경을 세팅하려 하니 windows 에서 pip install pysqlcipher3 으로는 아주 많은 에러가 발생해서 직접 빌드를 해야한다.
환경 #
- Windows 11
- Python 3.10.5
참고 링크 #
- https://myohyun.tistory.com/261
- https://blog.csdn.net/m0_37416991/article/details/130934309
- https://stackoverflow.com/questions/61718992/install-pysqlcipher3-windows
- https://stackoverflow.com/questions/55446420/issue-in-installing-pysqlcipher3
설치 #
-
github에서 pysqlcipher3 레포 클론
-
Win64 OpenSSL 설치 (lite 버전 X)
- https://slproweb.com/products/Win32OpenSSL.html
- 시스템 환경변수 추가
OPENSSL_CONF=C:\OpenSSL-Win64\bin\openssl.cfg libcrypto.def/lib,libssl.def/lib파일 복사 후 →libeay32.def/lib,ssleay32.def/lib로 이름 변경하고
C:\Program Files\OpenSSL-Win64\lib로 이동 64bit openssl이 32bit와 하위 호환이 안되는 것 같다.
-
sqlite-amalgamation.zip 다운로드
-
ActiveTcl 설치
-
visual studio 설치 (x64 Native Tools Command)
-
x64 Native Tools터미널에서 sqlcipher clone 경로로 이동 후nmake /f Makefile.msc명령실행.
빌드는 실패하지만 sqlite3.c, sqlite3.h 파일만 생기면 된다. -
pysqlcipher 클론 폴더에
amalgamation폴더를 생성하고 바로 위에서 만들어낸 sqlite3.c, sqlite3.h 파일을 옮긴다.amaligamation\sqlcipher폴더를 생성하고sqlite-amalgamation.zip을 압축 해제해서 나온 파일들을 집어넣는다.1pysqlcipher3 2├─amalgamation 3│ │ sqlite3.c 4│ │ sqlite3.h 5│ │ 6│ └─sqlcipher 7│ shell.c 8│ sqlite3.c 9│ sqlite3.h 10│ sqlite3ext.h -
$ python setup.py build_amalgamation명령을 실행하면 에러가 발생할텐데 고치면서 빌드를 완료한다. -
빌드가 완료되면
$ python setup.py install명령으로 설치한다. (관리자 권한 터미널이여야 함)
에러 없이 import 되면 성공!
error C2017: illegal escape sequence #
모듈네임이 파싱이 안돼서 생기는 문제기 때문에 에러가 발생하고 있는 파일에서 MODULE_NAME 부분을 전부 "pysqlcipher3.dbapi2" 로 수정해주면 된다.
처음엔 cache.c 겠지만, 계속 실행하다보면 connection.c 등 거의 모든 .c 파일에서 에러가 발생한다.
사용법 #
1from pysqlcipher3 import dbapi2 as sqlite
2
3key_bytes = bytes.fromhex("8e 51 0b 47 c7 25 16 39 4c f4 3d b7 9f bf 41 6f 61 2d b5 3e 43 ad 5f f2 dd 03 ee 4c a8 14 4b 5e ".replace(" ", ""))
4
5conn = sqlite.connect('test.db')
6c = conn.cursor()
7c.execute(f"PRAGMA key = \"x'{key_bytes.hex()}'\";")
8c.execute("PRAGMA cipher_compatibility = 3")
9c.execute('''create table stocks (date text, trans text, symbol text, qty real, price real)''')
10c.execute("""insert into stocks values ('2006-01-05','BUY','RHAT',100,35.14)""")
11conn.commit()
12
13c.execute("select * from stocks")
14t = c.fetchall()
15for f in t:
16 print(f)
17
18c.close()
파일을 hxd로 열어보면 암호화되어 있고, 같은 비밀번호로 다시 복호화가 잘 된다.
PRAGMA 세팅법 #
암호화할 때 PRAGMA를 세팅할 수 있다. key 세팅 이후에 적용해야 적용되는 듯 하다.
이중에 cipher 라고 암호화 방식을 지정하는게 있는데, sqlcipher는 사실상 AES-256-CBC 하나의 암호화 방식만 지원한다.
1import pysqlcipher3.dbapi2 as sqlite
2
3# 이 값들을 반복문으로 돌려볼 수도 있다.
4page_sizes = [512, 1024, 2048, 4096, 8192, 16384, 32768, 65536] # 다양한 페이지 크기
5kdf_iters = [1000, 4000, 10000, 64000, 128000, 256000, 512000] # KDF 반복 횟수
6hmac_algorithms = ["HMAC_SHA1", "HMAC_SHA256", "HMAC_SHA512"] # HMAC 알고리즘
7kdf_algorithms = ["PBKDF2_HMAC_SHA1", "PBKDF2_HMAC_SHA256", "PBKDF2_HMAC_SHA512"] # KDF 알고리즘
8
9# 데이터베이스 연결
10conn = sqlite.connect('encrypted_database.db')
11
12# 커서 생성
13cursor = conn.cursor()
14
15# 키를 설정하여 데이터베이스 암호화/복호화
16cursor.execute("PRAGMA key = 'your_password';")
17
18# 데이터베이스가 새로 만들어졌다면 암호화 시작
19cursor.execute("PRAGMA cipher_page_size = 4096;") # 페이지 크기 설정
20cursor.execute("PRAGMA cipher_plaintext_header_size = 32;") # 헤더 크기 설정 (32의 배수, 페이지 크기 미만)
21cursor.execute("PRAGMA kdf_iter = 64000;") # PBKDF2 키 스트레칭 설정
22cursor.execute("PRAGMA kdf_iter;") # 잘 세팅 됐는지 확인
23t = cursor.fetchone()
24print(f"kdf_iter 세팅 확인: {t}")
25cursor.execute("PRAGMA cipher_hmac_algorithm = HMAC_SHA512;") # HMAC 알고리즘 설정
26cursor.execute("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA512;") # KDF 알고리즘 설정
27cursor.execute("PRAGMA cipher_use_hmac = ON;") # HMAC 사용 여부 설정
28
29# 데이터 삽입 예시
30cursor.execute("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, data TEXT);")
31cursor.execute("INSERT INTO test (data) VALUES ('Hello, SQLCipher!');")
32
33# 변경 사항 저장
34conn.commit()
35
36# 연결 종료
37cursor.close()
38conn.close()
복호화 할때도 동일하게 PRAGMA를 세팅해줘야 복호화가 정상적으로 동작한다.
처음 키만 연결하고 PRAGMA값을 확인해보면 그냥 기본값이 들어가있다.
1import pysqlcipher3.dbapi2 as sqlite
2
3# 암호화된 데이터베이스 연결
4conn = sqlite.connect('encrypted_database.db')
5
6# 커서 생성
7cursor = conn.cursor()
8
9# 복호화 키 설정
10cursor.execute("PRAGMA key = 'your_password';")
11cursor.execute("PRAGMA cipher_page_size = 4096;")
12cursor.execute("PRAGMA cipher_plaintext_header_size = 32;")
13cursor.execute("PRAGMA kdf_iter = 64000;")
14cursor.execute("PRAGMA cipher_hmac_algorithm = HMAC_SHA512;")
15cursor.execute("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA512;")
16# cursor.execute("PRAGMA cipher_use_hmac = ON;")
17
18# 데이터 조회 예시
19cursor.execute("SELECT * FROM test;")
20rows = cursor.fetchall()
21
22for row in rows:
23 print(row)
24
25# 연결 종료
26cursor.close()
27conn.close()