2020년 7월 19일 일요일

소스 코드에 중요/계정/비밀번호 정보를 남기기


필요성

소스코드를 공유하거나 github에 공개될때 혹은 코드에 중요한 계정 정보를 그대로 두기가 찝찝한 경우가 있습니다. 계정 정보를 환경 변수에 넣는다고 하더라도 중요한 정보가 환경 변수 쪽으로 그대로 입력한 상태가 되도록 해야할텐데 그 정보가 날것 형태(raw)로 어딘가에는 저장될 수 밖에 없습니다. 그래서 해결책을 고민을 해봤습니다.

IDEA

암호화를 해야겠다고 고민을 하였으나 어떤 방식으로 어떻게 할까 고민을 하였습니다. 암호화된 값을 기록을 하고 암호화를 어떻게 할것이냐인데....
암호화의 키는 PC장치의 serial로 구현하였으며 미리 원하는 값을 해당 PC에서 암호화한 문자열을 소스에 기록해두고, 해당 시리얼이 유출되지 않는한 암호가 누출되지 않도록 작업하였습니다.


필요한 함수들


시리얼 구하는 함수 : get_serial_number.py


#https://gist.github.com/angeloped/3febaaf71ac083bc2cd5d99d775921d0
# wmic bios get serialnumber#Windows
# hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.uuid#Linux
# ioreg -l | grep IOPlatformSerialNumber#Mac OS X
import os, sys
def getMachine_addr():
	os_type = sys.platform.lower()
	if "win" in os_type:
		command = "wmic bios get serialnumber"
	elif "linux" in os_type:
		command = "hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.uuid"
	elif "darwin" in os_type:
		command = "ioreg -l | grep IOPlatformSerialNumber"
	return os.popen(command).read().replace("\n","").replace("	","").replace(" ","")

#output machine serial code: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
#print(getMachine_addr())


암호화 하는 함수 여기에서는 AES 암호화 사용 : crypto.py


#pip install pycryptodomex
import base64
import hashlib
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes

#__key__ = hashlib.sha256(b'k').digest()

def encrypt(raw,key):
    __key__ = hashlib.sha256(key).digest()
    BS = AES.block_size
    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)

    raw = base64.b64encode(pad(raw).encode('utf8'))
    iv = get_random_bytes(AES.block_size)
    cipher = AES.new(key= __key__, mode= AES.MODE_CFB,iv= iv)
    return base64.b64encode(iv + cipher.encrypt(raw))

def decrypt(enc,key):
    __key__ = hashlib.sha256(key).digest()
    unpad = lambda s: s[:-ord(s[-1:])]
    enc = base64.b64decode(enc)
    iv = enc[:AES.block_size]
    cipher = AES.new(__key__, AES.MODE_CFB, iv)
    return unpad(base64.b64decode(cipher.decrypt(enc[AES.block_size:])).decode('utf8'))

"""
import crypto
print(crypto.encrypt("FOO",b"key"))
print(crypto.decrypt(crypto.encrypt("FOO",b"key"),b"key"))
"""


암호화 해서 출력해보기 : password_enc.py


import crypto
import get_serial_number

print("Input string:")
data = input()

key = get_serial_number.getMachine_addr()
encdata = crypto.encrypt(data,key.encode())
print(encdata)
print(crypto.decrypt(encdata,key.encode()))

"""
import crypto
import get_serial_number
key = get_serial_number.getMachine_addr()
encdata = 'XXX'
decdata = crypto.decrypt(encdata,key.encode())
"""



사용해 보기


원하는 문자열 암호화하기 (여기에서는 'abcdef' ) 입력하였음
암호화된 문자열은 PC마다 다른 값을 가집니다.

C:\Users\USER\Documents\python\stock>python password_enc.py
Input string:
abcdef
b'WUUQsepngiVj+xmOfFH8k7fkqF1ifll3W/ZKjitbF5ou123123123cf2f3lng=='
abcdef


사용방법


암호화키 = get_serial_number.getMachine_addr()
암호해제된 문자열 = crypto.decrypt( 암호화된 문자열 ,암호화 키 )












댓글 없음:

댓글 쓰기