Lưu trữ giá trị băm SHA1 trong MySQL


160

Tôi có một câu hỏi đơn giản xảy ra khi tôi muốn lưu trữ kết quả của hàm băm SHA1 trong cơ sở dữ liệu MySQL:

Trường VARCHAR sẽ tồn tại trong bao lâu để tôi lưu trữ kết quả của hàm băm?


9
Nếu bạn vừa googled sha1, hãy nhấp vào cảm giác may mắn và bạn nên vào wikipedia nơi bạn có thể tìm thấy nó luôn là 160 bit.
Tim Matthews

Câu trả lời:


315

Tôi sẽ sử dụng VARCHARcho dữ liệu chiều dài thay đổi, nhưng không phải với dữ liệu chiều dài cố định. Vì giá trị SHA-1 luôn dài 160 bit, nên VARCHARsẽ chỉ lãng phí một byte bổ sung cho độ dài của trường có độ dài cố định .

Và tôi cũng sẽ không lưu trữ giá trị SHA1đang trở lại. Bởi vì nó chỉ sử dụng 4 bit cho mỗi ký tự và do đó sẽ cần 160/4 = 40 ký tự. Nhưng nếu bạn sử dụng 8 bit cho mỗi ký tự, bạn sẽ chỉ cần một trường dài 160/8 = 20 ký tự.

Vì vậy, tôi khuyên bạn nên sử dụng BINARY(20)UNHEXchức năng để chuyển đổi SHA1giá trị thành nhị phân.

Tôi so sánh các yêu cầu lưu trữ cho BINARY(20)CHAR(40).

CREATE TABLE `binary` (
    `id` int unsigned auto_increment primary key,
    `password` binary(20) not null
);
CREATE TABLE `char` (
    `id` int unsigned auto_increment primary key,
    `password` char(40) not null
);

Với hàng triệu hồ sơ binary(20)mất 44,56M, trong khi char(40)mất 64,57M. InnoDBđộng cơ.


2
Trong PostgreSQL, điều này sẽ chuyển sang sử dụng trường bytea, phải không?
mvexel

Giải pháp này rất hay, nhưng có một điểm khác để sử dụng char (40) với hexa sha1 - điều này được sử dụng rộng rãi hơn nhiều và sẽ có ít vấn đề chuyển đổi hơn trong mã ứng dụng.
Arthur Kushman

2
Lưu ý cho người dùng phpmyadmin. Khi lưu trữ hàm băm dưới dạng nhị phân, phpmyadmin sẽ hiển thị nó dưới dạng chuỗi hex, nhưng pma sẽ không thể sử dụng nó trong "tab tìm kiếm" được cung cấp. Sẽ chỉ hoạt động nếu bạn thêm UNHEX()thủ công vào sql.
Timo Huovinen

2
@Gumbo Bạn có thể lưu trữ một số lượng byte khác nhau trong một bytea. Bạn đang đề cập đến các yêu cầu lưu trữ của loại bytea. Đó là "1 hoặc 4 byte cộng với chuỗi nhị phân thực tế". Cái "1 hoặc 4" đề cập đến có thể là độ dài của dữ liệu được lưu trữ, vì bạn không thể sử dụng byte bằng 0 để kết thúc chuỗi như bạn làm với varchar. Điều đó ngụ ý, nhưng không được nêu trong hướng dẫn, rằng bạn có thể lưu trữ tới 2 ^ (8 * 4) hoặc hơn 4 gigabyte trong một bytea. postgresql.org/docs/9.0/static/datatype-binary.html Lưu trữ băm trong cơ sở dữ liệu postgres có thể sẽ nhỏ nhất dưới dạng cột bit hoặc bytea.
Viktor

2
dev.mysql.com/doc/refman/5.5/en/ từ cung cấp thông tin về hiệu suất và lưu trữ khi lưu trữ kết quả của các chức năng mã hóa
Clocker


11

Tham khảo lấy từ blog này:

Dưới đây là danh sách các thuật toán băm cùng với kích thước bit yêu cầu của nó:

  • MD5 = giá trị băm 128 bit.
  • SHA1 = giá trị băm 160 bit.
  • SHA224 = giá trị băm 224 bit.
  • SHA256 = giá trị băm 256 bit.
  • Giá trị băm SHA384 = 384 bit.
  • SHA512 = giá trị băm 512 bit.

Tạo một bảng mẫu với yêu cầu CHAR (n):

CREATE TABLE tbl_PasswordDataType
(
    ID INTEGER
    ,MD5_128_bit CHAR(32)
    ,SHA_160_bit CHAR(40)
    ,SHA_224_bit CHAR(56)
    ,SHA_256_bit CHAR(64)
    ,SHA_384_bit CHAR(96)
    ,SHA_512_bit CHAR(128)
); 
INSERT INTO tbl_PasswordDataType
VALUES 
(
    1
    ,MD5('SamplePass_WithAddedSalt')
    ,SHA1('SamplePass_WithAddedSalt')
    ,SHA2('SamplePass_WithAddedSalt',224)
    ,SHA2('SamplePass_WithAddedSalt',256)
    ,SHA2('SamplePass_WithAddedSalt',384)
    ,SHA2('SamplePass_WithAddedSalt',512)
);

10
Xin vui lòng, xin vui lòng , xin vui lòng không thực sự lưu trữ mật khẩu như thế này.
Berry M.

Hey berry, bạn có thể giải thích TẠI SAO của bạn? chi tiết
Anvesh

4
Lưu trữ băm mật khẩu đơn giản giúp mật khẩu được "trích xuất" dễ dàng hơn nhiều nếu cơ sở dữ liệu của bạn bị xâm phạm so với khi bạn sử dụng hàm băm mật khẩu (hy vọng được kéo dài). Đề nghị đọc: paragonie.com/blog/2016/02/how-safely-store-password-in-2016
matt

2
@ BlackBerryM. đọc điều này một năm sau đó và không nghĩ rằng ai đó đang nói về mật khẩu hoặc nếu mọi người vẫn sử dụng hàm băm đơn giản để lưu trữ dữ liệu xác thực. Nhưng họ làm: D
Rohit Hazra

6

Kích thước đầu ra của sha1 là 160 bit. Đó là 160/8 == 20 ký tự (nếu bạn sử dụng ký tự 8 bit) hoặc 160/16 = 10 (nếu bạn sử dụng ký tự 16 bit).


Giả sử các ký tự nhị phân 8 bit. 40 ký tự nếu được lưu dưới dạng hex.
Tyzoid

3

Vì vậy, độ dài nằm trong khoảng 10 ký tự 16 bit và 40 chữ số hex.

Trong mọi trường hợp, hãy quyết định định dạng bạn sẽ lưu trữ và đặt trường có kích thước cố định dựa trên định dạng đó. Bằng cách đó, bạn sẽ không có bất kỳ không gian lãng phí.


2

Bạn vẫn có thể muốn sử dụng VARCHAR trong trường hợp bạn không luôn lưu trữ hàm băm cho người dùng (nghĩa là xác thực tài khoản / quên url đăng nhập). Khi người dùng đã xác thực / thay đổi thông tin đăng nhập, họ không thể sử dụng hàm băm và không có lý do gì để làm. Bạn có thể tạo một bảng riêng để lưu trữ băm tạm thời -> các liên kết người dùng có thể bị xóa nhưng tôi không nghĩ rằng hầu hết mọi người bận tâm để làm điều này.


2

Nếu bạn cần một chỉ mục trên cột sha1, tôi đề nghị CHAR (40) vì lý do hiệu suất. Trong trường hợp của tôi, cột sha1 là mã thông báo xác nhận email, vì vậy trên trang đích, truy vấn chỉ nhập bằng mã thông báo. Trong trường hợp này CHAR (40) với INDEX, theo tôi, là sự lựa chọn tốt nhất :)

Nếu bạn muốn áp dụng phương pháp này, hãy nhớ để lại $ rawDefput = false.


1
Tại sao bạn không lập chỉ mục BINary (20)? Điều đó sẽ không nhanh bằng một nửa kích thước phải không?
nickdnk

Vâng, điều này ~ 5 năm trước nhưng tôi nghĩ rằng tôi đã đề cập đến thực tế là bạn vẫn cần mở khóa để thêm một số tải (+ làm cho ứng dụng khó bảo trì hơn và ít di động hơn?). Nó cũng phụ thuộc vào phần cứng của bạn, nếu bạn có ít bộ nhớ hơn và chậm nhất có lẽ là tốt nhất để bám vào nhị phân (20) nếu không tôi sẽ nói char (40). Khó có thể nói mà không chạy một số bài kiểm tra với ngôn ngữ và phần cứng bạn đang sử dụng và xem những gì phù hợp với bạn nhất.
Francesco Casula

1
Tôi cho rằng nếu bạn đang làm bất cứ điều gì khác ngoài việc chọn từ đâu unex (hash) = hash để tìm nạp một hàng, thì có lẽ bạn đã đúng. Nhưng việc giữ chỉ số được đệm sẽ chiếm gấp đôi bộ nhớ theo cách này.
nickdnk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.