web-dev-qa-db-ja.com

pythonスクリプトでのパスワードの非表示(安全でない難読化のみ)

python接続を作成しているODBCスクリプトがあります。 ODBC接続は、接続文字列を使用して生成されます。この接続文字列には、この接続のユーザー名とパスワードを含める必要があります。

ファイル内でこのパスワードをわかりにくくする簡単な方法はありますか(ファイルを編集しているときに誰もパスワードを読み取れないというだけです)?

115
bernhardrusch

Base64 encoding は標準ライブラリにあり、ショルダーサーファーを停止します。

>>> import base64
>>> print base64.b64encode("password")
cGFzc3dvcmQ=
>>> print base64.b64decode("cGFzc3dvcmQ=")
password
105
Dave Webb

Douglas F Shearerは、リモートログインにパスワードを指定する必要がある場合に、Unixで一般的に承認されているソリューションです。
パスを指定し、ファイルからプレーンテキストを読み取るための-password-from-fileオプションを追加します。
このファイルは、オペレーティングシステムで保護されたユーザー自身の領域に配置できます。また、さまざまなユーザーが独自のファイルを自動的に選択することもできます。

スクリプトのユーザーが知ることを許可されていないパスワードの場合-許可を高めてスクリプトを実行し、そのroot/adminユーザーがパスワードファイルを所有することができます。

49
Martin Beckett

簡単な方法を次に示します。

  1. pythonモジュールを作成します-peekaboo.pyと呼びましょう。
  2. Peekaboo.pyに、パスワードとそのパスワードを必要とするコードの両方を含めます
  3. このモジュールをインポートすることにより、コンパイル済みバージョン-peekaboo.pyc-を作成します(pythonコマンドラインなどを使用).
  4. 次に、peekaboo.pyを削除します。
  5. Peekaboo.pycのみに依存して、peekabooを楽しくインポートできるようになりました。 peekaboo.pycはバイトコンパイルされているため、一般ユーザーには読み込めません。

これは、base64デコードよりも少し安全です。ただし、py_to_pycデコンパイラに対して脆弱です。

45

Unixシステムで作業している場合は、標準のPythonライブラリのnetrcモジュールを利用してください。 here と記述された形式の別のテキストファイル(.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
26
jonasberg

ユーザーがユーザー名とパスワードを実行時に指定できないと仮定した場合の最善の解決策は、メインコードにインポートされるユーザー名とパスワードの変数の初期化のみを含む別のソースファイルです。このファイルは、資格情報が変更されたときにのみ編集する必要があります。それ以外の場合、平均的な記憶力を持つショルダーサーファーだけを心配しているのであれば、おそらくBase 64エンコードが最も簡単なソリューションです。 ROT13は手動でデコードするのは簡単すぎるだけでなく、大文字と小文字を区別せず、暗号化された状態であまりにも多くの意味を保持します。 pythonスクリプトの外部でパスワードとユーザーIDをエンコードします。実行時にスクリプトデコードを使用してください。

自動化されたタスクのスクリプト資格情報を提供することは、常に危険な提案です。スクリプトには独自の資格情報が必要であり、使用するアカウントには、必要なもの以外のアクセス権は一切許可されません。少なくともパスワードは長く、むしろランダムにする必要があります。

19
tduehr

スクリプト外部のファイルからユーザー名とパスワードをインポートするのはどうですか?そうすれば、誰かがスクリプトを手に入れても、パスワードは自動的に取得されません。

16

base64は、単純なニーズを満たす方法です。何もインポートする必要はありません。

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

python3base64を使用した難読化の方法は異なります。

import base64
base64.b64encode(b'PasswordStringAsStreamOfBytes')

結果として

b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM='

非公式の文字列表現に注意してください。実際の文字列は引用符で囲まれています

元の文字列にデコードして戻す

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

文字列オブジェクトが必要な場所でこの結果を使用するには、バイトオブジェクトをtranslated

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

python3がバイト(およびそれに応じて文字列)を処理する方法の詳細については、 公式ドキュメント を参照してください。

5
jitter

これは非常に一般的な問題です。通常、できることは次のいずれかです。

A)何らかの種類のシーザー暗号関数を作成して(rot13ではなく)エンコード/デコードするか、B)暗号化キーを使用して、プログラムの範囲内でパスワードをエンコード/デコードすることをお勧めします。ファイル保護を使用して、キーへのアクセスを保護できます。アプリがサービス/デーモン(Webサーバーなど)として実行される場合、これらの行に沿って、サービスのスタートアップの一部としてパスワードを入力して、パスワードで保護されたキーストアにキーを入れることができます。アプリを再起動するには管理者が必要になりますが、設定パスワードには非常に良い注意が必要です。

4
Patrick

認証/パスワード/ユーザー名を暗号化された詳細に変換するのではなく、より内製的な手法。 FTPLIBは単なる例です。 "pass.csv"はcsvファイル名です

以下のようにCSVでパスワードを保存します:

user_name

ユーザーのパスワード

(列見出しなし)

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])
2
LonelySoul

お使いのオペレーティングシステムは、おそらくデータを安全に暗号化する機能を提供します。たとえば、WindowsにはDPAPI(データ保護API)があります。初めて実行するときに資格情報をユーザーに求め、その後の実行のために暗号化してそれらを消去してみませんか

2
Jamie Eisenhart

構成情報を暗号化された構成ファイルに配置します。キーを使用してコードでこの情報を照会します。このキーを環境ごとに個別のファイルに配置し、コードと共に保存しないでください。

1
FlySwat

Windowsで実行している場合、win32cryptライブラリの使用を検討できます。スクリプトを実行しているユーザーが保護されたデータ(キー、パスワード)を保存および取得できるため、パスワードがコード内にクリアテキストまたは難読化された形式で保存されることはありません。他のプラットフォームに同等の実装があるかどうかはわかりません。そのため、win32cryptを厳密に使用すると、コードは移植できなくなります。

モジュールはここで入手できると思います: http://timgolden.me.uk/pywin32-docs/win32crypt.html

1
VilleLipponen

ネット上のPythonで書かれたいくつかのROT13ユーティリティがあります-それらのためだけにグーグル。 ROT13は、文字列をオフラインでエンコードし、ソースにコピーして、送信ポイントでデコードします。

しかし、これは本当に弱い保護です...

0
Kevin Little

ピットを知っていますか?

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
0
TakesxiSximada

これはあなたの質問に正確に答えるわけではありませんが、関連しています。コメントとして追加するつもりでしたが、許可されませんでした。私はこれと同じ問題に取り組んできましたが、Jenkinsを使用してユーザーにスクリプトを公開することにしました。これにより、サーバーで暗号化および保護され、管理者以外のユーザーがアクセスできない別のファイルにdb資格情報を保存できます。また、UIを作成し、実行を調整するための少しのショートカットが可能になります。

0
Joe Hayes

また、スクリプトの外部にパスワードを保存し、実行時にパスワードを提供する可能性を考慮することもできます

例えばfred.py

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
0
jalanb