반응형

예전에, 회사에서 파이썬으로 어떤 값을 사용해야 하는 순간이 있었는데 이 값이 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

+ Recent posts