Bir python komut dosyasında bir parolayı gizleme (yalnızca güvenli olmayan gizleme)


127

ODBC bağlantısı oluşturan bir python betiğim var. ODBC bağlantısı bir bağlantı dizesiyle oluşturulur. Bu bağlantı dizesinde, bu bağlantı için kullanıcı adı ve şifreyi eklemem gerekiyor.

Dosyada bu şifreyi gizlemenin kolay bir yolu var mı (sadece dosyayı düzenlerken kimse şifreyi okuyamaz)?


16
Bu dosyayı çalıştıran kullanıcıların en azından okuma erişimine sahip olacağını ve şifreleri kolayca alabileceğini unutmayın. Eğer inceler sadece sizin tarafınızdan okunabiliyorsa ve insanların onu omzunuzun üzerinden görmesinden endişe duyuyorsanız, ancak ortalama bir gözlemci bir şifreyi alacak kadar hızlı ezberleyemezken, komut dosyasına erişimi olan herhangi biri ve küçük bir miktar teknik bilgi birikimi ve az miktarda hırs parolalarınızı ele geçirmenizi sağlayacaktır. Güvenliği her zaman çok dikkatli düşünün, bu önemlidir.
Youarefunny

Yanıtlar:


117

Base64 kodlaması standart kitaplıktadır ve omuz sörfçülerini durdurmak için yapılır:

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

5
Katılıyorum. Base64 kodlu şifre çok daha gizemli görünüyor.
Ed Haber

4
Ancak betiğin, onu çalıştıran kullanıcı tarafından okunabilir olması ve parolanın olmaması gerektiği gerçeğine yardımcı olmaz.
Martin Beckett

79
Bunun bu bağlamda base64olduğundan daha iyi olduğunu düşünmüyorum rot13. Aksine, base64tipik özelliklerine (eşit işareti, ...) sahiptir ve bu nedenle diğer yaklaşımlardan daha kolay saptanabilir. Yine de herhangi bir gizlemenin pratik bir faydası yoktur. Bu cevabın bu kadar yüksek puan alması gerçekten kötü. Sadece yanlış bir güvenlik hissi veriyor ...
schlamar

12
Komut dosyası tarafından kullanılabilmesi için parolayı kaydediyorsanız, komut dosyasına erişimi olan herkes, hangi şifreleme yöntemini kullanırsanız kullanın, parolayı alabilecektir. Buradaki gereklilik, şifreyi, açıkken komut dosyasına bakan birinden gizlemekti. Bu durumda Python standart kitaplığında olduğu gibi base64tercih edilir rot13.
Dave Webb

17
base64 şifreleme DEĞİLDİR. en iyi ihtimalle şaşırtma.
csgeek

52

Douglas F Shearer, uzaktan oturum açma için bir parola belirlemeniz gerektiğinde, Unix'te genel olarak onaylanmış bir çözümdür.
Bir ekleme password-den-dosyasının yolunu belirtin ve bir dosyadan şifresiz okumak için seçenek.
Dosya daha sonra işletim sistemi tarafından korunan kullanıcının kendi alanında olabilir. Ayrıca, farklı kullanıcıların kendi dosyalarını otomatik olarak almalarına izin verir.

Komut dosyası kullanıcısının bilmesine izin verilmeyen şifreler için - komut dosyasını aşılmış izinle çalıştırabilir ve şifre dosyasının sahibi o kök / yönetici kullanıcısına sahip olabilirsiniz.


1
Komut dosyasını bir kök veya yönetici parolası vermeden yükseltilmiş izinlerle tam olarak nasıl çalıştırırsınız? UID bitlerini ayarlamakla ilgili mi?
Youarefunny

4
Boşver ben çözdüm. İlgilenen herkes için: Eğer bir betik setuid bit setine sahipse, işletim sistemi setuid bitini yorumlayıcıya ' aktarır ' . Ne yazık ki, çok büyük güvenlik açıkları vardır, bu nedenle çoğu modern dağıtım, komut dosyaları için setuid'i kapatır.
Youarefunny

--Password-from-file seçeneğinde herhangi bir bilgi bulamıyorum. Hiç örneğin var mı? Teşekkürler!
pyramidface

@pyramidface - Bunun gibi bir özelliği kodlayacağınızı ve bir dosyadan bir şifre okuma yeteneği ekleyeceğinizi kastetmiştim
Martin Beckett

@MartinBeckett, ancak Youarefunny'nin dediği gibi, betiğin şifre dosyasına kök erişimini sağlamak için python'da setuid'i yükseltmeniz gerekir mi?
pyramidface

51

İşte basit bir yöntem:

  1. Bir python modülü oluşturun - buna peekaboo.py diyelim.
  2. Peekaboo.py'de hem şifreyi hem de bu şifreyi gerektiren herhangi bir kodu ekleyin
  3. Bu modülü içe aktararak (python komut satırı vb. Aracılığıyla) derlenmiş bir sürüm - peekaboo.pyc - oluşturun.
  4. Şimdi, peekaboo.py'yi silin.
  5. Artık peekaboo'yu yalnızca peekaboo.pyc'ye dayanarak mutlu bir şekilde içe aktarabilirsiniz. Peekaboo.pyc byte derlendiğinden sıradan kullanıcılar tarafından okunamaz.

Bu, base64 kod çözme işleminden biraz daha güvenli olmalıdır - ancak bir py_to_pyc çözücüye karşı savunmasızdır.


2
Bunun hala bazı eksiklikleri var ama aslında istediğim şeye çok yakın. Ekrandaki parolayı göstermeden veya komut istemine yazmak zorunda kalmadan kullanıcı / passwd bağlantılarını içeren python komut dosyalarını göstermeme izin verecek. import peekabopeekaboo.passwordpassword='secret'
Peekaboo'yu içe aktardıktan

8
Eğer bir adım daha bu fikri almak istiyorsanız, kullanabileceğiniz Cython By ...: (vs, MacOS .bu, pencereler için .pyd ex) C içine herhangi .py dosyasını derlemek ve bir platforma özel ikili oluşturmak için cythonizingSenaryonuzun ve oluşturulan ikili dosyayı paylaşarak bu cevabın avantajını elde edeceksiniz + başka bir gizleme katmanı ekleyeceksiniz, çünkü artık şifreye ulaşmak için C kodunu derlemeniz var. Bu% 100 güvenli değildir, ancak gizlemek istediğiniz hassas verilere ulaşmak çok emek gerektirir.
Fnord

cythonizing, mükemmel
Arno

29

Bir Unix sistemi üzerinde çalışıyorsanız, standart Python kitaplığındaki netrc modülünden yararlanın. Bu biçim decribed sahip ayrı bir metin dosyası (.netrc), şifreleri okur burada .

İşte küçük bir kullanım örneği:

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

19

Kullanıcı adı ve parolanın kullanıcı tarafından çalışma zamanında verilemeyeceğini varsayan en iyi çözüm, muhtemelen ana kodunuza aktarılan kullanıcı adı ve parola için yalnızca değişken başlatma içeren ayrı bir kaynak dosyadır. Bu dosyanın yalnızca kimlik bilgileri değiştiğinde düzenlenmesi gerekir. Aksi takdirde, yalnızca ortalama belleğe sahip omuz sörfçüleri için endişeleniyorsanız, temel 64 kodlama muhtemelen en kolay çözümdür. ROT13'ün kodunu manuel olarak çözmek çok kolaydır, büyük / küçük harfe duyarlı değildir ve şifreli durumunda çok fazla anlam taşır. Python betiğinin dışında şifrenizi ve kullanıcı kimliğinizi kodlayın. Kullanım için çalışma zamanında kod çözmesini sağlayın.

Otomatik görevler için komut dosyalarına kimlik bilgileri vermek her zaman riskli bir tekliftir. Komut dosyanız kendi kimlik bilgilerine sahip olmalı ve kullandığı hesap, tam olarak gerekenden başka erişime sahip olmamalıdır. En azından şifre uzun ve rasgele olmalıdır.


Çok güzel cevap - teşekkür ederim. Yazdığım küçük betikler için (yine de bakım betikleri - BASE64 kodlaması yeterli olacaktır)
bernhardrusch

2
Kulağa hoş geliyor, ancak örnek bir uygulama verebilir misiniz? Şu anda bu sadece genel bir uygulamanın açıklaması ve bunu daha önce yapmamış biri için yararlı değil.
Dannid

18

Kullanıcı adını ve parolayı komut dosyasının dışındaki bir dosyadan içe aktarmaya ne dersiniz? Bu şekilde, birisi komut dosyasını ele geçirse bile, parolayı otomatik olarak alamaz.


15

base64, basit ihtiyaçlarınızı karşılamanın yoludur. Herhangi bir şeyi içe aktarmaya gerek yoktur:

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

2
Aptalca olan tam olarak nedir ?! Yanıtın tamamı mı yoksa içe aktarılmayan kısım mı?
tzot

18
Base64 yalnızca güvenlik yanılsamasını ekler.
FlySwat

13
Jonathan, soruyu okumamışsın gibi görünüyor. Bu belirsizlikle ilgili (ve çok geçici bir konu), güvenlikle değil , bu yüzden cevabımı neden yararlı bulmadığınızı anlamıyorum.
tzot

1
Base64 modülünü kullanmak yerine bunu yapabileceğinizi bilmiyordum. Ve zlib gibi bir çok kodlama da var ... eğlenceli :)
Kiv

1
@Dennis Bugünlerde base64 modülünü kullanmak tercih edilen yoldur. İkincisi artık Python'un yeni sürümlerinde çalışmıyor.
Jeyekomon

5

için python3 gizleme kullanılarak base64farklı yapılır:

import base64
base64.b64encode(b'PasswordStringAsStreamOfBytes')

hangi sonuçlanır

b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM='

gayri resmi dize temsiline dikkat edin, gerçek dize tırnak içindedir

ve orijinal dizeye geri kod çözme

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

dize nesnelerinin gerekli olduğu bu sonucu kullanmak için bayt nesnesi çevrilebilir

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

python3'ün baytları (ve buna göre dizeleri) nasıl işlediği hakkında daha fazla bilgi için lütfen resmi belgelere bakın .


4

Bu oldukça yaygın bir sorundur. Tipik olarak yapabileceğiniz en iyi şey,

A) kodlamak / deşifre etmek için bir tür ceasar şifreleme işlevi oluşturun (sadece rot13 değil) veya

B) tercih edilen yöntem, programınızın erişimi dahilinde bir şifreleme anahtarı kullanmaktır, şifreyi kodlamak / kodunu çözmek. Anahtar erişimini korumak için dosya korumasını kullanabilirsiniz.

Bu satırlar boyunca, uygulamanız bir hizmet / arka plan programı olarak çalışıyorsa (bir web sunucusu gibi), anahtarınızı hizmet başlangıcının bir parçası olarak şifre girişi ile şifre korumalı bir anahtar deposuna koyabilirsiniz. Uygulamanızı yeniden başlatmak için bir yönetici gerekecektir, ancak yapılandırma şifreleriniz için gerçekten iyi bir öngörü elde edeceksiniz.


2

İşletim sisteminiz muhtemelen verileri güvenli bir şekilde şifrelemek için olanaklar sağlar. Örneğin, Windows'ta DPAPI (veri koruma API'si) vardır. Neden ilk çalıştırdığınızda kullanıcıdan kimlik bilgilerini istemiyorsunuz ve ardından sonraki çalıştırmalar için şifrelenmiş olarak onu uzaklara çekmiyorsunuz?


2

Kimlik doğrulamasını / parolaları / kullanıcı adını şifrelenmiş ayrıntılara dönüştürmek yerine daha fazla yerel değerlendirme. FTPLIB sadece örnektir. " pass.csv ", csv dosyasının adıdır

Şifreyi CSV'ye aşağıdaki gibi kaydedin:

Kullanıcı adı

Kullanıcı şifresi

(Sütun başlığı olmadan)

CSV'yi okumak ve bir listeye kaydetmek.

Liste seçimlerini kimlik doğrulama ayrıntıları olarak kullanma.

Tam kod.

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

İşte böyle bir şey için pasajım. Temel olarak işlevi kodunuza aktarır veya kopyalarsınız. getCredentials, yoksa şifrelenmiş dosyayı oluşturur ve bir diksiyon döndürür ve updateCredential güncellenir.

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()

1

Yapılandırma bilgilerini şifrelenmiş bir yapılandırma dosyasına yerleştirin. Bu bilgiyi kodunuzda bir anahtar kullanarak sorgulayın. Bu anahtarı ortam başına ayrı bir dosyaya yerleştirin ve kodunuzla birlikte saklamayın.


1

Pit biliyor musun?

https://pypi.python.org/pypi/pit (yalnızca py2 (sürüm 0.3))

https://github.com/yoshiori/pit (py3 üzerinde çalışacak (mevcut sürüm 0.4))

test.py

from pit import Pit

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

Çalıştırmak:

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

~ / .Pit / default.yml:

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

3
Pit herhangi bir dokümantasyona sahip değil
successhawk

@Successhawk'ın da belirttiği gibi - "pit" için bu github / pypi bağlantılarında HİÇBİR dokümantasyon görmüyorum - ancak yukarıdaki açıklama açık - ve genel olarak, kimlik bilgilerini kolay görünümden "gizlemek" için bu çözümü seviyorum ...
netdesignate

Bakım yapılmayan bir modülü kullanmak konusunda isteksizim ve talimatlara uygun olarak kullanmaya çalıştığımda hatalar alıyorum:/usr/lib/python3.7/site-packages/pit.py:93: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details. return yaml.load(open(Pit._config))
netdesignate

1

Windows üzerinde çalışıyorsanız, win32crypt kitaplığını kullanmayı düşünebilirsiniz. Komut dosyasını çalıştıran kullanıcı tarafından korunan verilerin (anahtarlar, şifreler) depolanmasına ve alınmasına izin verir, böylece şifreler hiçbir zaman kodunuzda açık metin veya karmaşık biçimde saklanmaz. Diğer platformlar için eşdeğer bir uygulama olup olmadığından emin değilim, bu nedenle win32crypt'in sıkı kullanımıyla kodunuz taşınabilir değildir.

Modülün buradan edinilebileceğine inanıyorum: http://timgolden.me.uk/pywin32-docs/win32crypt.html


1

Bunu yapmanın bir yolu şudur:

Python kabuğunda:

>>> 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=='

Ardından, aşağıdaki kodla bir modül oluşturun:

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')

Bunu yaptıktan sonra, şifremi doğrudan içe aktarabilir veya gerektiğinde şifresini çözmek için jeton ve şifreyi içe aktarabilirsiniz.

Açıkçası, bu yaklaşımın bazı eksiklikleri var. Birisi hem jetona hem de anahtara sahipse (betiğe sahiplerse olduğu gibi), kolayca şifresini çözebilirler. Bununla birlikte, karmaşık hale getirir ve kodu (Nuitka gibi bir şeyle) derlerseniz, en azından şifreniz bir onaltılık düzenleyicide düz metin olarak görünmez.


0

Bu, sorunuza tam olarak cevap vermiyor, ancak ilgili. Yorum olarak ekleyecektim ama izin verilmedi. Ben de aynı sorunla uğraşıyorum ve senaryoyu Jenkins kullanan kullanıcılara göstermeye karar verdik. Bu, db kimlik bilgilerini, bir sunucuda şifrelenmiş ve güvenliği sağlanmış ve yönetici olmayanların erişemeyeceği ayrı bir dosyada saklamamıza olanak tanır. Ayrıca, bir kullanıcı arabirimi oluşturmak ve yürütmeyi kısmak için biraz kısayol sağlar.


0

Parolayı komut dosyası dışında depolama ve çalışma zamanında sağlama olasılığını da düşünebilirsiniz.

örneğin fred.py

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

hangisi gibi çalıştırılabilir

$ PASSWORD=password123 python fred.py
fred password123

Ekstra "belirsizlik yoluyla güvenlik" katmanları kullanılarak elde edilebilir base64 (yukarıda önerildiği gibi), kodda daha az belirgin adlar kullanılarak ve gerçek parolayı koddan daha da uzaklaştırarak elde edilebilir.

Kod bir havuzdaysa, sırları onun dışında saklamak genellikle yararlıdır , böylece kişi bunu ~/.bashrc(veya bir kasaya veya bir başlatma betiğine, ...) ekleyebilir.

export SURNAME=cGFzc3dvcmQxMjM=

ve değiştirmek fred.pyiçin

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

sonra yeniden giriş yapın ve

$ python fred.py
fred password123

0

Neden basit bir xor yok?

Avantajları:

  • ikili veriye benziyor
  • anahtarı bilmeden kimse okuyamaz (tek bir karakter olsa bile)

Genel sözcükler için basit b64 dizelerini ve rot13'ü tanıdığım noktaya geliyorum. Xor bunu daha da zorlaştırırdı.



-1

'Net'te Python'da yazılmış birkaç ROT13 yardımcı programı var - sadece onlar için google. ROT13 dizeyi çevrimdışı olarak kodlar, kaynağa kopyalar, iletim noktasında kodunu çözer.

Ama bu gerçekten zayıf bir koruma ...


bu yanıtı daha kullanışlı hale getirmek için lütfen bir bağlantı veya örnek kod ekleyin
Micah Stubbs
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.