Băm an toàn với Python Hashlib

Spread the love

Hướng dẫn này sẽ hướng dẫn bạn cách tạo hàm băm an toàn bằng cách sử dụng chức năng tích hợp sẵn từ mô-đun hashlib của Python.

Hiểu được tầm quan trọng của hàm băm và cách tính toán hàm băm an toàn theo chương trình có thể hữu ích—ngay cả khi bạn không làm việc trong lĩnh vực bảo mật ứng dụng. Nhưng tại sao?

Chà, khi làm việc với các dự án Python, bạn có thể sẽ gặp các trường hợp mà bạn lo lắng về việc lưu trữ mật khẩu và thông tin nhạy cảm khác trong cơ sở dữ liệu hoặc tệp mã nguồn. Trong những trường hợp như vậy, sẽ an toàn hơn khi chạy thuật toán băm trên thông tin nhạy cảm và lưu trữ hàm băm thay vì thông tin.

Trong hướng dẫn này, chúng tôi sẽ đề cập đến băm là gì và nó khác với mã hóa như thế nào. Chúng ta cũng sẽ xem xét các thuộc tính của hàm băm an toàn. Sau đó, chúng ta sẽ sử dụng các thuật toán băm phổ biến để tính toán hàm băm của văn bản gốc trong Python. Để làm điều này, chúng tôi sẽ sử dụng mô-đun hashlib tích hợp.

Đối với tất cả những điều này và hơn thế nữa, hãy bắt đầu!

Băm là gì?

Quá trình băm lấy một chuỗi thông báo và đưa ra đầu ra có độ dài cố định được gọi là hàm băm. Có nghĩa là độ dài của hàm băm đầu ra cho một thuật toán băm nhất định là cố định – bất kể độ dài của đầu vào. Nhưng nó khác với mã hóa như thế nào?

Trong mã hóa, tin nhắn hoặc văn bản thuần túy được mã hóa bằng thuật toán mã hóa cung cấp đầu ra được mã hóa. Sau đó, chúng tôi có thể chạy thuật toán giải mã trên đầu ra được mã hóa để lấy lại chuỗi thông báo.

Tuy nhiên, băm hoạt động khác nhau. Chúng tôi vừa biết được rằng quá trình mã hóa là không thể đảo ngược ở chỗ bạn có thể chuyển từ thư được mã hóa sang thư không được mã hóa và ngược lại.

Không giống như mã hóa, băm không phải là một quá trình không thể đảo ngược, nghĩa là chúng ta không thể chuyển từ hàm băm sang thông báo đầu vào.

Thuộc tính của hàm băm

Hãy xem nhanh một số thuộc tính mà hàm băm phải đáp ứng:

  • Tất định: Hàm băm là xác định. Đưa ra một tin nhắn m, hàm băm của m luôn giống nhau.
  • Preimage Resistant: Chúng tôi đã đề cập đến vấn đề này khi chúng tôi nói rằng băm không phải là một hoạt động không thể đảo ngược. Thuộc tính kháng ảnh trước cho biết rằng không thể tìm thấy thông báo m từ hàm băm đầu ra.
  • Chống va chạm: Rất khó (hoặc không khả thi về mặt tính toán) để tìm hai chuỗi thông báo khác nhau m1 và m2 sao cho hàm băm của m1 bằng với hàm băm của m2. Thuộc tính này được gọi là khả năng chống va chạm.
  • Khả năng chống tiền ảnh thứ hai: Điều này có nghĩa là đã cho một thông báo m1 và hàm băm m2 tương ứng, không thể tìm thấy một thông báo m2 khác sao cho hàm băm(m1) = hàm băm(m2).
  Cách hủy tư cách thành viên Shipt

Mô-đun hashlib của Python

Mô-đun hashlib tích hợp sẵn của Python cung cấp triển khai một số thuật toán băm và phân loại thông báo bao gồm thuật toán SHA và MD5.

Để sử dụng hàm tạo và hàm tích hợp từ mô-đun hashlib của Python, bạn có thể nhập nó vào môi trường làm việc của mình như sau:

import hashlib

Mô-đun hashlib cung cấp các hằng số algorithm_available và algorithm_guaranteed, biểu thị tập hợp các thuật toán có triển khai khả dụng và được đảm bảo tương ứng trên một nền tảng.

Do đó, các thuật toán_đảm bảo là một tập hợp con của các thuật toán_có sẵn.

Bắt đầu REPL Python, nhập hashlib và truy cập các hằng số algorithm_available và algorithm_guaranteed:

>>> hashlib.algorithms_available
# Output
{'md5', 'md5-sha1', 'sha3_256', 'shake_128', 'sha384', 'sha512_256', 'sha512', 'md4', 
'shake_256', 'whirlpool', 'sha1', 'sha3_512', 'sha3_384', 'sha256', 'ripemd160', 'mdc2', 
'sha512_224', 'blake2s', 'blake2b', 'sha3_224', 'sm3', 'sha224'}
>>> hashlib.algorithms_guaranteed
# Output
{'md5', 'shake_256', 'sha3_256', 'shake_128', 'blake2b', 'sha3_224', 'sha3_384', 
'sha384', 'sha256', 'sha1', 'sha3_512', 'sha512', 'blake2s', 'sha224'}

Chúng tôi thấy rằng các thuật toán_đảm bảo thực sự là một tập hợp con của các thuật toán_có sẵn

Cách tạo các đối tượng băm trong Python

Tiếp theo, hãy tìm hiểu cách tạo các đối tượng băm trong Python. Chúng tôi sẽ tính toán hàm băm SHA256 của chuỗi thông báo bằng các phương pháp sau:

  • Phương thức khởi tạo new() chung
  • Constructor dành riêng cho thuật toán

Sử dụng Trình tạo mới ()

Hãy khởi tạo chuỗi tin nhắn:

>>> message = "techpoe.com is awesome!"

Để khởi tạo đối tượng băm, chúng ta có thể sử dụng hàm tạo new() và chuyển vào tên của thuật toán như sau:

>>> sha256_hash = hashlib.new("SHA256")

Bây giờ chúng ta có thể gọi phương thức update() trên đối tượng băm với chuỗi thông báo làm đối số:

>>> sha256_hash.update(message)

Nếu bạn làm như vậy, bạn sẽ gặp lỗi vì thuật toán băm chỉ có thể hoạt động với chuỗi byte.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Unicode-objects must be encoded before hashing

Để lấy chuỗi mã hóa, bạn có thể gọi phương thức encode() trên chuỗi phương thức, sau đó sử dụng nó trong lệnh gọi phương thức update(). Sau khi làm như vậy, bạn có thể gọi phương thức hexdigest() để lấy hàm băm sha256 tương ứng với chuỗi thông báo.

sha256_hash.update(message.encode())
sha256_hash.hexdigest()
# Output:'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'

Thay vì mã hóa chuỗi tin nhắn bằng phương thức encode(), bạn cũng có thể định nghĩa nó là một chuỗi byte bằng cách thêm b vào trước chuỗi như sau:

message = b"techpoe.com is awesome!"
sha256_hash.update(message)
sha256_hash.hexdigest()
# Output: 'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'

Hàm băm thu được giống với hàm băm trước đó, điều này xác nhận tính chất xác định của hàm băm.

  9 công cụ tìm kiếm trên Internet mà bạn có thể chưa từng nghe đến

Ngoài ra, một thay đổi nhỏ trong chuỗi thông báo sẽ khiến hàm băm thay đổi đáng kể (còn được gọi là “hiệu ứng tuyết lở”).

Để xác minh điều này, hãy thay đổi ‘a’ trong ‘awesome’ thành ‘A’ và tính hàm băm:

message = "techpoe.com is Awesome!"
h1 = hashlib.new("SHA256")
h1.update(message.encode())
h1.hexdigest()
# Output: '3c67f334cc598912dc66464f77acb71d88cfd6c8cba8e64a7b749d093c1a53ab'

Chúng tôi thấy rằng hàm băm thay đổi hoàn toàn.

Sử dụng Trình xây dựng dành riêng cho thuật toán

Trong ví dụ trước, chúng ta đã sử dụng hàm tạo new() chung và chuyển vào “SHA256” làm tên của thuật toán để tạo đối tượng băm.

Thay vì làm như vậy, chúng ta cũng có thể sử dụng hàm tạo sha256() như sau:

sha256_hash = hashlib.sha256()
message= "techpoe.com is awesome!"
sha256_hash.update(message.encode())
sha256_hash.hexdigest()
# Output: 'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'

Hàm băm đầu ra giống hệt với hàm băm mà chúng tôi đã thu được trước đó cho chuỗi thông báo “techpoe.com thật tuyệt vời!”.

Khám phá các thuộc tính của đối tượng băm

Các đối tượng băm có một vài thuộc tính hữu ích:

  • Thuộc tính digest_size biểu thị kích thước của bản tóm tắt tính bằng byte. Ví dụ: thuật toán SHA256 trả về hàm băm 256 bit, tương đương với 32 byte
  • Thuộc tính block_size đề cập đến kích thước khối được sử dụng trong thuật toán băm.
  • Thuộc tính name là tên của thuật toán mà chúng ta có thể sử dụng trong hàm tạo new(). Tra cứu giá trị của thuộc tính này có thể hữu ích khi các đối tượng băm không có tên mô tả.

Chúng ta có thể kiểm tra các thuộc tính này cho đối tượng sha256_hash mà chúng ta đã tạo trước đó:

>>> sha256_hash.digest_size
32
>>> sha256_hash.block_size
64
>>> sha256_hash.name
'sha256'

Tiếp theo, chúng ta hãy xem xét một số ứng dụng băm thú vị bằng cách sử dụng mô-đun hashlib của Python.

Ví dụ thực tế về băm

Xác minh tính toàn vẹn của phần mềm và tệp

Là nhà phát triển, chúng tôi luôn tải xuống và cài đặt các gói phần mềm. Điều này đúng bất kể bạn đang làm việc trên bản phân phối Linux hay trên Windows hay Mac.

Tuy nhiên, một số máy nhân bản cho các gói phần mềm có thể không đáng tin cậy. Bạn có thể tìm thấy hàm băm (hoặc tổng kiểm tra) bên cạnh liên kết tải xuống. Và bạn có thể xác minh tính toàn vẹn của phần mềm đã tải xuống bằng cách tính toán hàm băm và so sánh nó với hàm băm chính thức.

  “IDK” có nghĩa là gì, và bạn sử dụng nó như thế nào?

Điều này cũng có thể được áp dụng cho các tệp trên máy của bạn. Ngay cả thay đổi nhỏ nhất trong nội dung tệp cũng sẽ thay đổi đáng kể hàm băm, bạn có thể kiểm tra xem tệp đã bị sửa đổi hay chưa bằng cách xác minh hàm băm.

Đây là một ví dụ đơn giản. Tạo một tệp văn bản ‘my_file.txt’ trong thư mục làm việc và thêm một số nội dung vào đó.

$ cat my_file.txt
This is a sample text file.
We are  going to compute the SHA256 hash of this text file and also
check if the file has been modified by
recomputing the hash.

Sau đó, bạn có thể mở tệp ở chế độ đọc nhị phân (‘rb’), đọc nội dung của tệp và tính toán hàm băm SHA256 như được hiển thị:

>>> import hashlib
>>> with open("my_file.txt","rb") as file:
...     file_contents = file.read()
...     sha256_hash = hashlib.sha256()
...     sha256_hash.update(file_contents)
...     original_hash = sha256_hash.hexdigest()

Ở đây, biến original_hash là hàm băm của ‘my_file.txt’ ở trạng thái hiện tại.

>>> original_hash
# Output: '53bfd0551dc06c4515069d1f0dc715d002d451c8799add29f3e5b7328fda9f8f'

Bây giờ hãy sửa đổi tệp ‘my_file.txt’. Bạn có thể xóa khoảng trắng thừa ở đầu trước từ ‘going’. 🙂

Tính toán lại hàm băm và lưu trữ nó trong biến computed_hash.

>>> import hashlib
>>> with open("my_file.txt","rb") as file:
...     file_contents = file.read()
...     sha256_hash = hashlib.sha256()
...     sha256_hash.update(file_contents)
...     computed_hash = sha256_hash.hexdigest()

Sau đó, bạn có thể thêm một câu lệnh khẳng định đơn giản để xác nhận xem computed_hash có bằng original_hash hay không.

>>> assert computed_hash == original_hash

Nếu tệp bị sửa đổi (điều này đúng trong trường hợp này), bạn sẽ nhận được lỗi AssertionError:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

Bạn có thể sử dụng hàm băm khi lưu trữ thông tin nhạy cảm, chẳng hạn như mật khẩu trong cơ sở dữ liệu. Bạn cũng có thể sử dụng hàm băm trong xác thực mật khẩu khi kết nối với cơ sở dữ liệu. Xác thực hàm băm của mật khẩu đã nhập so với hàm băm của mật khẩu chính xác.

Phần kết luận

Tôi hy vọng hướng dẫn này đã giúp bạn tìm hiểu về cách tạo hàm băm an toàn bằng Python. Dưới đây là những điểm chính:

  • Mô-đun hashlib của Python cung cấp các triển khai sẵn sàng sử dụng của một số thuật toán băm. Bạn có thể nhận danh sách các thuật toán được đảm bảo trên nền tảng của mình bằng cách sử dụng hashlib.algorithms_guaranteed.
  • Để tạo một đối tượng băm, bạn có thể sử dụng hàm tạo new() chung với cú pháp: hashlib.new(“algo-name”). Ngoài ra, bạn có thể sử dụng hàm tạo tương ứng với các thuật toán băm cụ thể, chẳng hạn như: hashlib.sha256() cho hàm băm SHA 256.
  • Sau khi khởi tạo chuỗi thông báo cần băm và đối tượng băm, bạn có thể gọi phương thức update() trên đối tượng băm, tiếp theo là phương thức hexdigest() để lấy hàm băm.
  • Tính năng băm có thể hữu ích khi kiểm tra tính toàn vẹn của các tạo phẩm và tệp phần mềm, lưu trữ thông tin nhạy cảm trong cơ sở dữ liệu, v.v.

Tiếp theo, hãy tìm hiểu cách viết mã trình tạo mật khẩu ngẫu nhiên bằng Python.

x