[windows] pysqlcipher3 사용하기
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와 하위 호환이 안되는 것 같다.
06c4593c-b96f-4ffd-830f-28abc1273c73
-
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을 압축 해제해서 나온 파일들을 집어넣는다.pysqlcipher3 ├─amalgamation │ │ sqlite3.c │ │ sqlite3.h │ │ │ └─sqlcipher │ shell.c │ sqlite3.c │ sqlite3.h │ sqlite3ext.h -
$ python setup.py build_amalgamation명령을 실행하면 에러가 발생할텐데 고치면서 빌드를 완료한다. -
빌드가 완료되면
$ python setup.py install명령으로 설치한다. (관리자 권한 터미널이여야 함)
에러 없이 import 되면 성공!
0c92b343-4125-4038-998f-20946cff0d53
error C2017: illegal escape sequence
모듈네임이 파싱이 안돼서 생기는 문제기 때문에 에러가 발생하고 있는 파일에서 MODULE_NAME 부분을 전부 "pysqlcipher3.dbapi2" 로 수정해주면 된다.
처음엔 cache.c 겠지만, 계속 실행하다보면 connection.c 등 거의 모든 .c 파일에서 에러가 발생한다.
사용법
from pysqlcipher3 import dbapi2 as sqlite
key_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(" ", ""))
conn = sqlite.connect('test.db')
c = conn.cursor()
c.execute(f"PRAGMA key = \"x'{key_bytes.hex()}'\";")
c.execute("PRAGMA cipher_compatibility = 3")
c.execute('''create table stocks (date text, trans text, symbol text, qty real, price real)''')
c.execute("""insert into stocks values ('2006-01-05','BUY','RHAT',100,35.14)""")
conn.commit()
c.execute("select * from stocks")
t = c.fetchall()
for f in t:
print(f)
c.close()
파일을 hxd로 열어보면 암호화되어 있고, 같은 비밀번호로 다시 복호화가 잘 된다.
PRAGMA 세팅법
암호화할 때 PRAGMA를 세팅할 수 있다. key 세팅 이후에 적용해야 적용되는 듯 하다.
이중에 cipher 라고 암호화 방식을 지정하는게 있는데, sqlcipher는 사실상 AES-256-CBC 하나의 암호화 방식만 지원한다.
import pysqlcipher3.dbapi2 as sqlite
# 이 값들을 반복문으로 돌려볼 수도 있다.
page_sizes = [512, 1024, 2048, 4096, 8192, 16384, 32768, 65536] # 다양한 페이지 크기
kdf_iters = [1000, 4000, 10000, 64000, 128000, 256000, 512000] # KDF 반복 횟수
hmac_algorithms = ["HMAC_SHA1", "HMAC_SHA256", "HMAC_SHA512"] # HMAC 알고리즘
kdf_algorithms = ["PBKDF2_HMAC_SHA1", "PBKDF2_HMAC_SHA256", "PBKDF2_HMAC_SHA512"] # KDF 알고리즘
# 데이터베이스 연결
conn = sqlite.connect('encrypted_database.db')
# 커서 생성
cursor = conn.cursor()
# 키를 설정하여 데이터베이스 암호화/복호화
cursor.execute("PRAGMA key = 'your_password';")
# 데이터베이스가 새로 만들어졌다면 암호화 시작
cursor.execute("PRAGMA cipher_page_size = 4096;") # 페이지 크기 설정
cursor.execute("PRAGMA cipher_plaintext_header_size = 32;") # 헤더 크기 설정 (32의 배수, 페이지 크기 미만)
cursor.execute("PRAGMA kdf_iter = 64000;") # PBKDF2 키 스트레칭 설정
cursor.execute("PRAGMA kdf_iter;") # 잘 세팅 됐는지 확인
t = cursor.fetchone()
print(f"kdf_iter 세팅 확인: {t}")
cursor.execute("PRAGMA cipher_hmac_algorithm = HMAC_SHA512;") # HMAC 알고리즘 설정
cursor.execute("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA512;") # KDF 알고리즘 설정
cursor.execute("PRAGMA cipher_use_hmac = ON;") # HMAC 사용 여부 설정
# 데이터 삽입 예시
cursor.execute("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, data TEXT);")
cursor.execute("INSERT INTO test (data) VALUES ('Hello, SQLCipher!');")
# 변경 사항 저장
conn.commit()
# 연결 종료
cursor.close()
conn.close()
복호화 할때도 동일하게 PRAGMA를 세팅해줘야 복호화가 정상적으로 동작한다.
처음 키만 연결하고 PRAGMA값을 확인해보면 그냥 기본값이 들어가있다.
import pysqlcipher3.dbapi2 as sqlite
# 암호화된 데이터베이스 연결
conn = sqlite.connect('encrypted_database.db')
# 커서 생성
cursor = conn.cursor()
# 복호화 키 설정
cursor.execute("PRAGMA key = 'your_password';")
cursor.execute("PRAGMA cipher_page_size = 4096;")
cursor.execute("PRAGMA cipher_plaintext_header_size = 32;")
cursor.execute("PRAGMA kdf_iter = 64000;")
cursor.execute("PRAGMA cipher_hmac_algorithm = HMAC_SHA512;")
cursor.execute("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA512;")
# cursor.execute("PRAGMA cipher_use_hmac = ON;")
# 데이터 조회 예시
cursor.execute("SELECT * FROM test;")
rows = cursor.fetchall()
for row in rows:
print(row)
# 연결 종료
cursor.close()
conn.close()
Comments