Tin tức và phân tích của tất cả các thiết bị di động

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

Hướng dẫn này sẽ hướng dẫn bạn cách tạo các hàm băm an toàn bằng cách sử dụng chức năng tích hợp của 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 quan tâm đến bảo mật ứng dụng. Nhưng tại sao?

Chà, khi làm việc trên các dự án Python, bạn có thể gặp phải trường hợp 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 này, sẽ an toàn hơn nếu 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 ta sẽ thảo luận về băm là gì và nó khác với mã hóa như thế nào. Chúng ta cũng sẽ thảo luận về các thuộc tính của hàm băm an toàn. Tiếp theo, 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 văn bản thuần túy trong Python. Để làm điều này, chúng tôi sẽ sử dụng mô-đun hashlib tích hợp sẵn.

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à tạo ra đầu ra có độ dài cố định gọi là hàm băm. Điều này có nghĩa là độ dài của hàm băm đầu ra đối với thuật toán băm nhất định là không đổi – bất kể độ dài của đầu vào. Nhưng nó khác với mã hóa như thế nào?

Với 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 tạo ra đầu ra được mã hóa. Sau đó chúng ta có thể chạy thuật toán giải mã trên đầu ra được mã hóa để khôi phục 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 rằng quá trình mã hóa có thể đảo ngược vì bạn có thể chuyển từ tin nhắn được mã hóa sang tin nhắn 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 có thể đảo ngược, nghĩa là chúng ta không thể chuyển từ băm sang thông báo đầu vào.

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

Chúng ta hãy xem nhanh một số thuộc tính mà hàm băm nên có:

  • Xác định: Hàm băm có tính xác định. Cho một thông điệp m, hàm băm m luôn giống nhau.
  • Chống tiền ảnh: Chúng tôi đã đề cập đến vấn đề này khi nói rằng việc trộn không phải là một thao tác có thể đảo ngược. Thuộc tính độ mạnh của tiền ảnh cho biết rằng việc tìm kiếm thông điệp m từ hàm băm đầu ra là không khả thi.
  • Chống va chạm: Sẽ 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 hàm băm của m2. Thuộc tính này được gọi là khả năng va chạm.
  • Chống tiền ảnh thứ hai: Điều này có nghĩa là với một thông báo m1 và hàm băm m2 tương ứng của nó, 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).

Mô-đun hashlib 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à băm thông báo, bao gồm thuật toán SHA và MD5.

Để sử dụng hàm tạo và hàm dựng sẵn từ mô-đun hashlib của python, bạn có thể nhập nó vào bàn làm việc của mình như sau:

import hashlib

Mô-đun hashlib cung cấp constant_algorithms_available và terms_guaranteed, nghĩa là một tập hợp các thuật toán có khả năng triển khai tương ứng và được đảm bảo trên nền tảng.

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

Chạy REPL Python, nhập hashlib và truy cập các hằng số có sẵn và các thuật toán được đảm bảo:

>>> 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 được đả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 đối tượng băm trong python

Tiếp theo, hãy tìm hiểu cách tạo đố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:

  • Hàm tạo new() chung.
  • Các hàm tạo dành riêng cho thuật toán

Sử dụng hàm tạo new().

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

>>> message = "newsblog.pl is awesome!"

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

>>> 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 làm 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 một chuỗi được mã hóa, bạn có thể gọi phương thức Encode() trên chuỗi phương thức và sau đó sử dụng nó trong lệnh gọi phương thức update(). Sau khi thực hiện xong, bạn có thể gọi phương thức hexdigest() để lấy hàm băm sha256 của chuỗi thông báo.

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

Thay vì mã hóa chuỗi thông báo bằng phương thức Encode(), bạn cũng có thể định nghĩa nó dưới dạng chuỗi byte bằng cách thêm tiền tố b vào trước chuỗi đó như thế này:

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

Hàm băm kết quả giống với hàm băm trước đó, điều này khẳng định tính chất xác định của hàm băm.

Ngoài ra, một thay đổi nhỏ trong chuỗi thông báo sẽ dẫn đến thay đổi hàm băm mạnh mẽ (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 “tuyệt vời” thành “A” và tính hàm băm:

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

Chúng ta có thể thấy rằng hàm băm thay đổi hoàn toàn.

Sử dụng hàm tạo dành riêng cho thuật toán

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

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

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

Giá trị băm đầu ra giống với giá trị băm mà chúng ta nhận được trước đó cho chuỗi thông báo “newsblog.pl thật tuyệt vời!”.

Nghiên cứu các thuộc tính của các đối tượng trộn

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

  • Thuộc tính dig_size chỉ định kích thước 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(). Việc tìm kiếm giá trị của thuộc tính này có thể hữu ích khi các đối tượng lối tắt 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 được tạo trước đó:

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

Tiếp theo, hãy xem xét một số cách sử dụng thú vị để băm bằ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 tin

Với tư cách 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 chạy bản phân phối Linux hay hệ thống Windows hoặc Mac.

Tuy nhiên, một số gói phần mềm nhân bản 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. 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.

Điều này cũng có thể được áp dụng cho các tập tin trên máy tính của bạn. Ngay cả một thay đổi nhỏ nhất đối với nội dung của tệp cũng sẽ thay đổi đáng kể hàm băm, bạn có thể kiểm tra xem tệp có bị sửa đổi hay không 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 của bạn 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 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, 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ể loại bỏ các khoảng trắng thừa ở đầu từ “go”. 🙂

Tính toán hàm băm một lần nữa và lưu trữ nó trong biến comped_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 để kiểm tra xem comped_hash có bằng hàm băm ban đầu hay không.

>>> assert computed_hash == original_hash

Nếu tệp đang được sửa đổi (điều này đúng trong trường hợp này), bạn sẽ nhận được 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 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 minh 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.

Ứng dụng

Tôi hy vọng hướng dẫn này đã giúp bạn tìm hiểu cách tạo hàm băm an toàn trong Python. Dưới đây là những kết luận quan trọng nhất:

  • 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 với 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 các hàm tạo tương ứng với các thuật toán băm cụ thể, ví dụ: hashlib.sha256() cho hàm băm SHA 256.
  • Sau khi chuỗi thông báo băm và đối tượng băm đã được khởi tạo, bạn có thể gọi phương thức update() trên đối tượng băm và sau đó gọi phương thức hexdigest() để lấy hàm băm.
  • Băm có thể hữu ích khi kiểm tra tính toàn vẹn của các thành phần phần mềm và tệp, lưu trữ thông tin nhạy cảm trong cơ sở dữ liệu, v.v.

Sau đó tìm hiểu cách viết mã trình tạo mật khẩu ngẫu nhiên bằng Python.