반응형
예전에, 회사에서 파이썬으로 어떤 값을 사용해야 하는 순간이 있었는데 이 값이 Node.js의 crypto.createCipher로 암호화되어 있었다. aes-256-ctr 방식인 건 알겠는데 문제는 예전에 만들어진 코드라 디프리케이티드된 crypto.createCipher를 사용했다는 것…
지금은 crypto.createCipher 대신 crypto.createCipheriv를 사용하는 걸 권장하고 있고 메소드명처럼 iv 값을 입력받는다. crypto.createCipher는 iv를 입력받지 않는데 파이썬 aes-256-ctr 복호화 예제를 찾아보면 전부 iv 값을 입력받고 있다. (모르는데 어떻게 입력해요!)
그래서 구교수님께 한참 찾아보다가 저 방식이 OpenSSL 비표준 방식이라는 걸 알았다. 해당 키워드로 다시 찾아보니 방법을 찾을 수 있었다.
const crypto = require('node:crypto');
const encrypt = (key, text) => {
const cipher = crypto.createCipher('aes-256-ctr', key);
let output = cipher.update(text, 'utf8', 'hex');
output += cipher.final('hex');
return output;
};
const decrypt = (key, text) => {
const decipher = crypto.createDecipher('aes-256-ctr', key);
let output = decipher.update(text, 'hex', 'utf8');
output += decipher.final('utf8');
return output;
};
console.log(encrypt('secret', 'Hello, world!'));
위와 같은 nodejs 코드로 암호화하면 1295189f8f6fefab62428b40d8라는 값을 얻을 수 있다.
파이썬의 pycryptodome 패키지를 사용하면 아래 코드로 복호화할 수 있다. (pip로 pycryptodome 설치 필요)
import binascii
from hashlib import md5
from Crypto.Cipher import AES
from Crypto.Util import Counter
# https://stackoverflow.com/questions/13907841/implement-openssl-aes-encryption-in-python
def EVP_BytesToKey(password, salt, key_len, iv_len):
dtot = md5(password + salt).digest()
d = [dtot]
while len(dtot) < (iv_len + key_len):
d.append(md5(d[-1] + password + salt).digest())
dtot += d[-1]
return dtot[:key_len], dtot[key_len : key_len + iv_len]
def decrypt(key, text):
key, iv = EVP_BytesToKey(key.encode("utf-8"), "".encode("utf-8"), 32, 16)
counter = Counter.new(AES.block_size * 8, initial_value=int(iv.hex(), 16))
cipher = AES.new(key, AES.MODE_CTR, counter=counter)
output = cipher.decrypt(binascii.unhexlify(text)).decode("utf-8")
return output
print(decrypt("secret", "1295189f8f6fefab62428b40d8"))
주석에 남긴 것처럼 이곳에서 답을 얻어서 코드를 만들었다. 원본값인 Hello, world!를 얻을 수 있다.
처음에 2.7로 짰다가 3으로 바꾸려니 문자열 인코딩 관련으로 고생했다는 후문..ㅎㅎ
반응형
'프로그래밍 > Python' 카테고리의 다른 글
[자작] DJ DJ pump this party (0) | 2023.03.04 |
---|---|
파이썬 타입 체크 (2) | 2021.02.13 |
파이썬 코딩 컨벤션 정리 (0) | 2020.08.08 |
pyc & pyo 디컴파일러, Easy Python Decompiler (3) | 2020.03.21 |
[자작] SteamGifts 알리미 (0) | 2019.06.21 |
메시지박스 띄우기 (1) | 2016.10.03 |
중복 실행 방지 (0) | 2016.08.14 |