programing

Python 스크립트에서 암호 숨기기(안전하지 않은 난독화만 해당)

muds 2023. 6. 10. 09:51
반응형

Python 스크립트에서 암호 숨기기(안전하지 않은 난독화만 해당)

ODBC 연결을 만드는 파이썬 스크립트가 있습니다.ODBC 연결은 연결 문자열을 사용하여 생성됩니다.이 연결 문자열에 이 연결에 대한 사용자 이름과 암호를 포함해야 합니다.

파일에서 이 암호를 숨기는 쉬운 방법이 있습니까(파일을 편집할 때 아무도 암호를 읽을 수 없습니다)?

Base64 인코딩은 표준 라이브러리에 있으며 어깨 서퍼를 중지하는 데 사용됩니다.

>>> import base64
>>>  print(base64.b64encode("password".encode("utf-8")))
cGFzc3dvcmQ=
>>> print(base64.b64decode("cGFzc3dvcmQ=").decode("utf-8"))
password

간단한 방법은 다음과 같습니다.

  1. 파이썬 모듈을 만듭니다. peekaboo.py 이라고 부릅니다.
  2. peekaboo.py 에서 암호와 해당 암호가 필요한 코드를 모두 포함합니다.
  3. peekaboo.pyc - 이 모듈을 가져와 컴파일된 버전을 만듭니다(python 명령줄 등을 통해).
  4. 이제 peekaboo.py 을 삭제합니다.
  5. 이제 peekaboo.pyc에만 의존하여 peekaboo를 기꺼이 가져올 수 있습니다.빼꼼이 이후로.pycis 바이트 컴파일되어 일반 사용자가 읽을 수 없습니다.

이것은 base64 디코딩보다 약간 더 안전해야 합니다. 하지만 py_to_pyc 디컴파일러에 취약합니다.

Douglas F Shearer's는 원격 로그인에 대한 암호를 지정해야 할 때 Unix에서 일반적으로 승인된 솔루션입니다.
--password-from-file 옵션을 추가하여 경로를 지정하고 파일에서 일반 텍스트를 읽습니다.
그러면 파일이 운영 체제에 의해 보호되는 사용자 자신의 영역에 있을 수 있습니다.또한 다양한 사용자가 자신의 파일을 자동으로 선택할 수 있습니다.

스크립트 사용자가 알 수 없는 암호의 경우 고급 권한으로 스크립트를 실행하고 해당 루트/관리자가 암호 파일을 소유할 수 있습니다.

유닉스 시스템에서 작업하는 경우 표준 Python 라이브러리에 있는 netrc 모듈을 활용합니다.여기에 설명된 형식이 있는 별도의 텍스트 파일(.netrc)에서 암호를 읽습니다.

다음은 작은 사용 예입니다.

import netrc

# Define which host in the .netrc file to use
HOST = 'mailcluster.loopia.se'

# Read from the .netrc file in your home directory
secrets = netrc.netrc()
username, account, password = secrets.authenticators( HOST )

print username, password

스크립트 외부 파일에서 사용자 이름과 암호를 가져오는 것은 어떻습니까?이렇게 하면 누군가가 스크립트를 손에 넣더라도 자동으로 암호를 얻을 수 없습니다.

사용자가 런타임에 사용자 이름과 암호를 지정할 수 없다고 가정하는 가장 좋은 해결책은 기본 코드로 가져온 사용자 이름과 암호에 대한 변수 초기화만 포함하는 별도의 소스 파일일 것입니다.이 파일은 자격 증명이 변경될 때만 편집해야 합니다.그렇지 않으면, 평균 메모리를 가진 어깨 서퍼들만 걱정된다면, 베이스 64 인코딩이 아마도 가장 쉬운 해결책일 것입니다.ROT13은 수동으로 디코딩하기가 너무 쉽고 대소문자를 구분하지 않으며 암호화된 상태에서 의미를 너무 많이 유지합니다.Python 스크립트 외부에서 암호와 사용자 ID를 인코딩합니다.런타임에 스크립트 디코딩을 사용하도록 합니다.

자동화된 작업에 대한 스크립트 자격 증명을 제공하는 것은 항상 위험한 제안입니다.스크립트에는 고유한 자격 증명이 있어야 하며 스크립트에서 사용하는 계정에는 필요한 것 이외의 액세스 권한이 없어야 합니다.적어도 암호는 길고 임의여야 합니다.

base64는 간단한 요구사항을 충족하는 방법입니다.아무것도 가져올 필요가 없습니다.

>>> 'your string'.encode('base64')
'eW91ciBzdHJpbmc=\n'
>>> _.decode('base64')
'your string'

이 작업을 수행하는 방법은 다음과 같습니다.

파이썬 쉘에서:

>>> from cryptography.fernet import Fernet
>>> key = Fernet.generate_key()
>>> print(key)
b'B8XBLJDiroM3N2nCBuUlzPL06AmfV4XkPJ5OKsPZbC4='
>>> cipher = Fernet(key)
>>> password = "thepassword".encode('utf-8')
>>> token = cipher.encrypt(password)
>>> print(token)
b'gAAAAABe_TUP82q1zMR9SZw1LpawRLHjgNLdUOmW31RApwASzeo4qWSZ52ZBYpSrb1kUeXNFoX0tyhe7kWuudNs2Iy7vUwaY7Q=='

그런 다음 다음 코드로 모듈을 만듭니다.

from cryptography.fernet import Fernet

# you store the key and the token
key = b'B8XBLJDiroM3N2nCBuUlzPL06AmfV4XkPJ5OKsPZbC4='
token = b'gAAAAABe_TUP82q1zMR9SZw1LpawRLHjgNLdUOmW31RApwASzeo4qWSZ52ZBYpSrb1kUeXNFoX0tyhe7kWuudNs2Iy7vUwaY7Q=='

# create a cipher and decrypt when you need your password
cipher = Fernet(key)

mypassword = cipher.decrypt(token).decode('utf-8')

이렇게 하면 내 암호를 직접 가져오거나 토큰과 암호를 가져와 필요에 따라 암호를 해독할 수 있습니다.

분명히, 이 접근법에는 몇 가지 단점이 있습니다.다른 사용자가 토큰과 키를 모두 가지고 있는 경우(스크립트가 있는 경우와 마찬가지로) 쉽게 암호를 해독할 수 있습니다.그러나 그것은 난독화되며, 만약 당신이 (누이트카와 같은 것으로) 코드를 컴파일한다면, 적어도 당신의 비밀번호는 16진수 편집기에서 일반 텍스트로 나타나지 않을 것입니다.

python3 난독화의 경우 사용base64다르게 수행됩니다.

import base64
base64.b64encode(b'PasswordStringAsStreamOfBytes')

결과적으로

b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM='

비공식 문자열 표현에 유의하십시오. 실제 문자열은 따옴표로 표시됩니다.

그리고 원래 문자열로 다시 디코딩합니다.

base64.b64decode(b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=')
b'PasswordStringAsStreamOfBytes'

문자열 개체가 필요한 경우 이 결과를 사용하여 바이트 개체를 변환할 수 있습니다.

repr = base64.b64decode(b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=')
secret = repr.decode('utf-8')
print(secret)

python3가 바이트(및 그에 따른 문자열)를 처리하는 방법에 대한 자세한 내용은 공식 문서를 참조하십시오.

이것은 꽤 흔한 문제입니다.일반적으로 다음 중 하나를 수행하는 것이 최선입니다.

암호화/암호화를 위한 일종의 시저 암호 함수를 만듭니다(단, rot13이 아님).

선호되는 방법은 암호화 키를 사용하여 프로그램이 접근할 수 있는 범위 내에서 암호를 인코딩/해제하는 것입니다.파일 보호를 사용하여 키 액세스를 보호할 수 있습니다.

이와 같이 앱이 서비스/데몬(웹 서버처럼)으로 실행되는 경우 서비스 시작 시 암호를 입력하여 암호로 보호되는 키 저장소에 키를 넣을 수 있습니다.앱을 다시 시작하려면 관리자가 필요하지만 구성 암호를 매우 잘 보호할 수 있습니다.

운영 체제는 데이터를 안전하게 암호화할 수 있는 기능을 제공합니다.예를 들어 Windows에는 DPAPI(데이터 보호 API)가 있습니다.처음 실행할 때 사용자에게 자격 증명을 요청하고 이후 실행을 위해 암호화된 자격 증명을 수집하는 것은 어떻습니까?

그런 것들을 위한 제 스니펫이 여기 있습니다.기본적으로 함수를 가져오거나 코드에 복사합니다.getCredentials는 암호화된 파일이 없는 경우 해당 파일을 만들고 사전을 반환하며 updateCredential은 업데이트됩니다.

import os

def getCredentials():
    import base64

    splitter='<PC+,DFS/-SHQ.R'
    directory='C:\\PCT'

    if not os.path.exists(directory):
        os.makedirs(directory)

    try:
        with open(directory+'\\Credentials.txt', 'r') as file:
            cred = file.read()
            file.close()
    except:
        print('I could not file the credentials file. \nSo I dont keep asking you for your email and password everytime you run me, I will be saving an encrypted file at {}.\n'.format(directory))

        lanid = base64.b64encode(bytes(input('   LanID: '), encoding='utf-8')).decode('utf-8')  
        email = base64.b64encode(bytes(input('   eMail: '), encoding='utf-8')).decode('utf-8')
        password = base64.b64encode(bytes(input('   PassW: '), encoding='utf-8')).decode('utf-8')
        cred = lanid+splitter+email+splitter+password
        with open(directory+'\\Credentials.txt','w+') as file:
            file.write(cred)
            file.close()

    return {'lanid':base64.b64decode(bytes(cred.split(splitter)[0], encoding='utf-8')).decode('utf-8'),
            'email':base64.b64decode(bytes(cred.split(splitter)[1], encoding='utf-8')).decode('utf-8'),
            'password':base64.b64decode(bytes(cred.split(splitter)[2], encoding='utf-8')).decode('utf-8')}

def updateCredentials():
    import base64

    splitter='<PC+,DFS/-SHQ.R'
    directory='C:\\PCT'

    if not os.path.exists(directory):
        os.makedirs(directory)

    print('I will be saving an encrypted file at {}.\n'.format(directory))

    lanid = base64.b64encode(bytes(input('   LanID: '), encoding='utf-8')).decode('utf-8')  
    email = base64.b64encode(bytes(input('   eMail: '), encoding='utf-8')).decode('utf-8')
    password = base64.b64encode(bytes(input('   PassW: '), encoding='utf-8')).decode('utf-8')
    cred = lanid+splitter+email+splitter+password
    with open(directory+'\\Credentials.txt','w+') as file:
        file.write(cred)
        file.close()

cred = getCredentials()

updateCredentials()

구성 정보를 암호화된 구성 파일에 넣습니다.키를 사용하여 코드에서 이 정보를 쿼리합니다.이 키를 환경별로 별도의 파일에 저장하고 코드와 함께 저장하지 마십시오.

인증/암호/사용자 이름을 암호화된 세부 정보로 변환하는 대신 자체 개발된 평가 기능을 제공합니다.FTPLIB는 단지 예시일 뿐입니다."pass.csv"는 CSV 파일 이름입니다.

아래와 같이 CSV에 암호를 저장합니다.

user_name

user_password

(열 제목 없음)

CSV를 읽고 목록에 저장합니다.

목록 요소를 인증 세부 정보로 사용합니다.

전체 코드.

import os
import ftplib
import csv 
cred_detail = []
os.chdir("Folder where the csv file is stored")
for row in csv.reader(open("pass.csv","rb")):       
        cred_detail.append(row)
ftp = ftplib.FTP('server_name',cred_detail[0][0],cred_detail[1][0])

피트를 아십니까?

https://pypi.python.org/pypi/pit (py2 전용(버전 0.3))

https://github.com/yoshiori/pit (py3(현재 버전 0.4)에서 작동합니다.)

test.py

from pit import Pit

config = Pit.get('section-name', {'require': {
    'username': 'DEFAULT STRING',
    'password': 'DEFAULT STRING',
    }})
print(config)

실행:

$ python test.py
{'password': 'my-password', 'username': 'my-name'}

~/.pit/default.yml:

section-name:
  password: my-password
  username: my-name

Windows에서 실행 중인 경우 win32crypt 라이브러리를 사용할 수 있습니다.스크립트를 실행하는 사용자가 보호된 데이터(키, 암호)를 저장하고 검색할 수 있으므로 암호는 코드에 일반 텍스트나 난독화된 형식으로 저장되지 않습니다.다른 플랫폼과 동등한 구현이 있는지 잘 모르겠습니다. 따라서 win32crypt를 엄격하게 사용하면 코드를 휴대할 수 없습니다.

모듈은 여기에서 구할 수 있다고 생각합니다. http://timgolden.me.uk/pywin32-docs/win32crypt.html

스크립트 외부에 암호를 저장하고 런타임에 암호를 제공할 수도 있습니다.

예: 프레드파이의

import os
username = 'fred'
password = os.environ.get('PASSWORD', '')
print(username, password)

처럼 운영할 수 있는

$ PASSWORD=password123 python fred.py
fred password123

을 통한 인 계층은 사무여하의명 "보안다있"수추계가달니습성층할을다음을을 으로써 달성될 수 있습니다.base64(위에서 제안한 바와 같이) 코드에서 덜 명확한 이름을 사용하고 실제 암호와 코드 사이를 더 멀리합니다.

만약 코드가 저장소에 있다면, 그것은 종종 그것 밖에 비밀을 저장하는 것에 유용합니다, 그래서 당신은 이것을 추가할 수 있습니다.~/.bashrc스크립트로으)로 이동합니다.

export SURNAME=cGFzc3dvcmQxMjM=

변경 그고변화리fred.py

import os
import base64
name = 'fred'
surname = base64.b64decode(os.environ.get('SURNAME', '')).decode('utf-8')
print(name, surname)

그리고 나서 다시 시작하고.

$ python fred.py
fred password123

간단한 xor를 갖는 게 어때요?

장점:

  • 이진 데이터처럼 보입니다.
  • 키를 모르면 아무도 읽을 수 없습니다(단일 문자라도).

저는 일반적인 단어에 대한 간단한 b64 문자열을 인식하고 rot13도 인식하는 시점에 도달합니다.Xor는 그것을 훨씬 더 어렵게 만들 것입니다.

'Net'에는 파이썬으로 작성된 몇 가지 ROT13 유틸리티가 있습니다. 단지 구글에서만 사용할 수 있습니다. ROT13은 문자열을 오프라인으로 인코딩하여 소스에 복사하고 전송 시점에서 디코딩합니다.

하지만 이건 정말 약한 보호장치야...

이것은 당신의 질문에 정확하게 답하지는 않지만, 그것은 관련이 있습니다.저는 댓글을 달려고 했지만 허락되지 않았습니다.저는 이와 같은 문제를 다뤄왔고, 우리는 젠킨스를 사용하는 사용자들에게 스크립트를 노출시키기로 결정했습니다.이렇게 하면 암호화되어 서버에 보호되며 비관리자가 액세스할 수 없는 별도의 파일에 DB 자격 증명을 저장할 수 있습니다.또한 UI를 만들고 조절 실행을 위한 약간의 바로 가기를 허용합니다.

import base64
print(base64.b64encode("password".encode("utf-8")))
print(base64.b64decode(b'cGFzc3dvcmQ='.decode("utf-8")))

언급URL : https://stackoverflow.com/questions/157938/hiding-a-password-in-a-python-script-insecure-obfuscation-only

반응형