Cách lưu trữ tên người dùng và mật khẩu trong Python

Giải pháp tốt hơn là lưu trữ "hàm băm một chiều" của mật khẩu, thường sử dụng hàm như

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
0 hoặc
database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
0

tài khoản người dùngsha1(mật khẩu)john@hotmail. com5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8betty@gmail. comcbfdac6008f9cab4083784cbd1874f76618d2a97

Mặc dù máy chủ không lưu trữ mật khẩu văn bản thuần túy ở bất kỳ đâu nhưng nó vẫn có thể xác thực người dùng

def is_password_correct(user, password_attempt):
    return sha1(password_attempt) == user["sha1_password"]

Phân tích

Giải pháp này an toàn hơn lưu trữ mật khẩu văn bản thuần túy, vì theo lý thuyết, không thể "hoàn tác" hàm băm một chiều và tìm một chuỗi đầu vào tạo ra cùng một giá trị băm. Thật không may, tin tặc đã tìm ra cách xung quanh điều này

hậu quả xấu

Một vấn đề là nhiều hàm băm (bao gồm cả

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
0 và
database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
0) xét cho cùng không phải là "một chiều" và các chuyên gia bảo mật đề xuất rằng các hàm này không được sử dụng nữa cho các ứng dụng bảo mật. (Thay vào đó, bạn nên sử dụng các hàm băm tốt hơn như
database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
3 cho đến nay chưa có bất kỳ lỗ hổng nào được biết đến. )

Nhưng có một vấn đề lớn hơn. tin tặc hoàn toàn không cần phải "hoàn tác" hàm băm; . Điều này tương tự như thử tất cả các kết hợp của khóa kết hợp. Đây là mã sẽ trông như thế nào

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"

Bạn có thể nghĩ rằng có quá nhiều mật khẩu khả thi để kỹ thuật này khả thi. Nhưng có ít mật khẩu phổ biến hơn nhiều so với bạn nghĩ. Hầu hết mọi người sử dụng mật khẩu dựa trên các từ trong từ điển (có thể thêm một vài số hoặc chữ cái). Và hầu hết các hàm băm như sha1() có thể được thực thi rất nhanh -- một máy tính thực sự có thể thử hàng tỷ kết hợp mỗi giây. Điều đó có nghĩa là hầu hết các mật khẩu có thể được tìm ra trong vòng chưa đầy 1 giờ cpu. Các chương trình như John The Ripper có thể làm điều này

Qua một bên. nhiều năm trước, máy tính không nhanh như vậy, vì vậy cộng đồng hacker đã tạo ra các bảng cầu vồng đã tính toán trước một tập hợp lớn các giá trị băm này trước thời hạn. Ngày nay, không ai sử dụng bảng cầu vồng nữa vì máy tính đủ nhanh mà không cần chúng

Vì vậy, tin xấu là bất kỳ người dùng nào có mật khẩu đơn giản như "password" hoặc "password123" hoặc bất kỳ mật khẩu nào trong số hàng tỷ mật khẩu có khả năng xảy ra cao nhất đều sẽ bị đoán mật khẩu. Nếu bạn có một mật khẩu cực kỳ phức tạp (hơn 16 số và chữ cái ngẫu nhiên), có lẽ bạn đã an toàn

Cũng lưu ý rằng đoạn mã trên đang tấn công hiệu quả tất cả các mật khẩu cùng một lúc. Không thành vấn đề nếu có 10 người dùng trong cơ sở dữ liệu của bạn hoặc 10 triệu, tin tặc sẽ không mất nhiều thời gian để đoán mật khẩu phù hợp. Tất cả vấn đề là tin tặc có thể lặp lại các mật khẩu tiềm năng nhanh như thế nào. (Và trên thực tế, việc có nhiều người dùng thực sự giúp ích cho tin tặc, vì nhiều khả năng ai đó trong hệ thống đã sử dụng mật khẩu "password123". )

sha1(password) là những gì LinkedIn sử dụng để lưu trữ mật khẩu của nó. Và vào năm 2012, một lượng lớn mật khẩu đã bị rò rỉ. Theo thời gian, tin tặc có thể tìm ra mật khẩu văn bản thuần túy cho hầu hết các hàm băm này

Tóm lược. lưu trữ một hàm băm đơn giản (không có muối) không an toàn -- nếu tin tặc giành được quyền truy cập vào cơ sở dữ liệu của bạn, chúng sẽ có thể tìm ra phần lớn mật khẩu của người dùng

Một nỗ lực để làm cho mọi thứ an toàn hơn là "muối" mật khẩu trước khi băm nó

tài khoản người dùngsha1("salt123456789" + mật khẩu)john@hotmail. comb467b644150eb350bbc1c8b44b21b08af99268aabetty@gmail. com31aa70fd38fee6f1f8b3142942ba9613920dfea0.

Muối ăn

Muối được cho là một chuỗi byte dài ngẫu nhiên. Nếu tin tặc có quyền truy cập vào các hàm băm mật khẩu mới này (nhưng không phải là muối), thì tin tặc sẽ khó đoán mật khẩu hơn nhiều vì chúng cũng cần biết muối.

hậu quả xấu

Tuy nhiên, nếu tin tặc đã đột nhập vào máy chủ của bạn, họ cũng có thể có quyền truy cập vào mã nguồn của bạn, vì vậy họ cũng sẽ biết được điều đó. Đó là lý do tại sao các nhà thiết kế bảo mật chỉ giả định điều tồi tệ nhất và không tin rằng muối là bí mật

Nhưng ngay cả khi muối không phải là một bí mật, thì việc sử dụng những chiếc bàn cầu vồng kiểu cũ mà tôi đã đề cập trước đây vẫn khó sử dụng hơn. (Những bảng cầu vồng đó được xây dựng với giả định là không có muối, vì vậy hàm băm có muối sẽ ngăn chặn chúng. ) Tuy nhiên, vì không ai sử dụng bảng cầu vồng nữa nên việc thêm một loại muối cố định không giúp được gì nhiều. Tin tặc vẫn có thể thực hiện cùng một vòng lặp cơ bản ở trên

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(SALT + password) in database_table:
        print "Hacker wins! I guessed a password!", password

Tóm lược

thêm một loại muối cố định vẫn không đủ an toàn

Bước tiếp theo trong bảo mật là tạo một cột mới trong cơ sở dữ liệu và lưu trữ một loại muối khác nhau cho mỗi người dùng. Muối được tạo ngẫu nhiên khi tài khoản người dùng được tạo lần đầu (hoặc khi người dùng thay đổi mật khẩu của họ)

tài khoản người dùngaltsha1(muối + mật khẩu)john@hotmail. com2dc7fcc. 1a74404cb136dd60041dbf694e5c2ec0e7d15b42betty@gmail. comfadb2f. e33ab75f29a9cf3f70d3fd14a7f47cd752e9c550

Xác thực người dùng không khó hơn nhiều so với trước đây

def is_password_correct(user, password_attempt):
    return sha1(user["salt"] + password_attempt) == user["password_hash"]

Tin tặc

Bằng cách có muối cho mỗi người dùng, chúng tôi nhận được một lợi ích to lớn. tin tặc không thể tấn công tất cả mật khẩu người dùng của bạn cùng một lúc

Thay vào đó, mã tấn công của anh ta phải thử từng người dùng một

for user in users:
    PER_USER_SALT = user["salt"]

    for password in LIST_OF_COMMON_PASSWORDS:
        if sha1(PER_USER_SALT + password) in database_table:
            print "Hacker wins! I guessed a password!", password

Vì vậy, về cơ bản, nếu bạn có 1 triệu người dùng, việc có muối cho mỗi người dùng sẽ khiến việc tìm ra mật khẩu của tất cả người dùng của bạn khó hơn gấp 1 triệu lần. Nhưng điều này vẫn không phải là không thể đối với một hacker. Thay vì 1 giờ cpu, giờ đây họ cần 1 triệu cpu giờ, có thể dễ dàng thuê từ Amazon với giá khoảng 40.000 đô la

Vấn đề thực sự với tất cả các hệ thống mà chúng ta đã thảo luận cho đến nay là các hàm băm như sha1() (hoặc thậm chí sha256()) có thể được thực thi trên mật khẩu với tốc độ 100M+/giây (hoặc thậm chí nhanh hơn bằng cách sử dụng GPU). Mặc dù các hàm băm này được thiết kế có tính đến bảo mật, nhưng chúng cũng được thiết kế sao cho chúng sẽ nhanh khi được thực thi trên các đầu vào dài hơn như toàn bộ tệp. dòng dưới cùng. các hàm băm này không được thiết kế để sử dụng cho việc lưu trữ mật khẩu

Thay vào đó, có một tập hợp các hàm băm được thiết kế riêng cho mật khẩu. Ngoài chức năng băm "một chiều" an toàn, chúng còn được thiết kế để hoạt động chậm.

Một ví dụ là Bcrypt

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
4 mất khoảng 100 mili giây để tính toán, chậm hơn sha1() khoảng 10.000 lần. 100 mili giây đủ nhanh để người dùng không nhận thấy khi họ đăng nhập, nhưng đủ chậm để việc thực thi đối với một danh sách dài các mật khẩu có khả năng trở nên kém khả thi hơn. Chẳng hạn, nếu một hacker muốn tính toán bcrypt() dựa trên danh sách một tỷ mật khẩu có khả năng xảy ra, sẽ mất khoảng 30.000 giờ cpu (khoảng 1200 đô la) -- và đó là cho một mật khẩu duy nhất. Chắc chắn không phải là không thể, nhưng còn nhiều việc hơn hầu hết các tin tặc sẵn sàng làm

cách thức hoạt động của Bcrypt

Về cơ bản, "mẹo" là nó thực thi hàm mã hóa/băm nội bộ nhiều lần trong một vòng lặp. (Có những lựa chọn thay thế khác cho Bcrypt, chẳng hạn như

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
5 sử dụng thủ thuật tương tự. )

Ngoài ra, Bcrypt có thể định cấu hình, với tham số log_rounds cho biết số lần thực thi hàm băm bên trong đó. Nếu đột nhiên, Intel tung ra một máy tính mới nhanh hơn 1000 lần so với máy tính hiện đại nhất hiện nay, bạn có thể định cấu hình lại hệ thống của mình để sử dụng log_rounds nhiều hơn 10 lần so với trước đây (

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
6 là logarit), điều này sẽ hủy bỏ

Bởi vì bcrypt() quá chậm nên ý tưởng về các bảng cầu vồng lại trở nên hấp dẫn, do đó, muối cho mỗi người dùng được tích hợp vào hệ thống Bcrypt. Trên thực tế, các thư viện như bcrypt trên pypi lưu trữ muối trong cùng một chuỗi với hàm băm mật khẩu, vì vậy bạn thậm chí sẽ không phải tạo một cột cơ sở dữ liệu riêng cho muối

1. Đầu tiên, hãy cài đặt nó

def is_password_correct(user, password_attempt):
    return sha1(password_attempt) == user["sha1_password"]
1

2. Mã Python khi tạo tài khoản người dùng mới (hoặc đặt lại mật khẩu của họ)

def is_password_correct(user, password_attempt):
    return sha1(password_attempt) == user["sha1_password"]
2

Hãy phân tích chuỗi đầu ra đó một chút

Cách lưu trữ tên người dùng và mật khẩu trong Python
Như bạn có thể thấy, nó lưu trữ cả muối và đầu ra được băm trong chuỗi. Nó cũng lưu trữ tham số
database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
6 được sử dụng để tạo mật khẩu, kiểm soát lượng công việc (i. e. nó chậm như thế nào) để tính toán

Nếu bạn muốn hàm băm chậm hơn, bạn chuyển một giá trị lớn hơn cho

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
8

def is_password_correct(user, password_attempt):
    return sha1(password_attempt) == user["sha1_password"]
5

Trong mọi trường hợp, bạn lưu trữ chuỗi này trong cơ sở dữ liệu và khi cùng người dùng đó cố gắng đăng nhập, bạn truy xuất cùng giá trị được băm đó và thực hiện việc này

def is_password_correct(user, password_attempt):
    return sha1(password_attempt) == user["sha1_password"]
6

Bạn có thể thắc mắc tại sao bạn lại chuyển hàm băm dưới dạng đối số salt sang

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
9

Lý do điều này hiệu quả là hàm

database_table = {
  "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8": "[email protected]",
  "cbfdac6008f9cab4083784cbd1874f76618d2a97": "[email protected]",
  ...}

for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(password) in database_table:
        print "Hacker wins! I guessed a password!"
9 thông minh và có thể trích xuất muối từ chuỗi
for password in LIST_OF_COMMON_PASSWORDS:
    if sha1(SALT + password) in database_table:
        print "Hacker wins! I guessed a password!", password
1 đó

Điều này thật tuyệt, vì điều đó có nghĩa là bạn không bao giờ phải tự mình lưu trữ, phân tích cú pháp hoặc xử lý bất kỳ giá trị muối nào -- giá trị duy nhất bạn cần xử lý là chuỗi băm duy nhất chứa mọi thứ bạn cần

Làm cách nào để lưu trữ email và mật khẩu trong Python?

Các bước liên quan để chạy chương trình lưu trữ tài khoản email .
Cài đặt thư viện Python và Tkinter
Trong thư mục gốc có tệp tên là “main” dùng để lưu trữ tên, email và mật khẩu
Trong thư mục gốc có tệp tên “emails” dùng để mã hóa tên, email và mật khẩu

Làm cách nào để đặt mật khẩu trong Python?

Dự án Python tạo mật khẩu bảo mật cao. .
nhập ngẫu nhiên. .
in (chuỗi. in được).
char_seq = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. #$.
print("Nhập độ dài yêu cầu của mật khẩu từ 8 đến 16. ").
nếu chiều dài >= 8 và chiều dài <= 16. .
khác. .
pip cài đặt trình tạo mật khẩu ngẫu nhiên

Làm cách nào để lưu mật khẩu được mã hóa bằng Python?

Các bước. .
Nhập khẩu dương xỉ
Sau đó tạo khóa mã hóa, có thể được sử dụng để mã hóa và giải mã
Chuyển đổi chuỗi thành chuỗi byte để có thể mã hóa
Ví dụ lớp Fernet với khóa mã hóa
Sau đó mã hóa chuỗi bằng ví dụ Fernet

Làm cách nào để lưu trữ khóa bí mật trong Python?

Một trong những phương pháp đơn giản và cơ bản nhất là lưu thông tin đăng nhập vào một tệp python khác nói bí mật. py và nhập nó vào tệp được yêu cầu . Chúng ta cần phải. gitignore những bí mật. tập tin py.