Tôi đã đọc về việc Git sử dụng thông báo SHA-1 làm ID cho bản sửa đổi. Tại sao nó không sử dụng một phiên bản SHA hiện đại hơn?
Tôi đã đọc về việc Git sử dụng thông báo SHA-1 làm ID cho bản sửa đổi. Tại sao nó không sử dụng một phiên bản SHA hiện đại hơn?
Câu trả lời:
Tại sao nó không sử dụng một phiên bản SHA hiện đại hơn?
Tháng 12 năm 2017: Nó sẽ. Và Git 2.16 (Q1 2018) là bản phát hành đầu tiên minh họa và thực hiện ý định đó.
Lưu ý: xem Git 2.19 bên dưới: nó sẽ là SHA-256 .
Git 2.16 sẽ đề xuất một cơ sở hạ tầng để xác định hàm băm nào được sử dụng trong Git và sẽ bắt đầu nỗ lực tìm kiếm hàm băm đó trong các đường dẫn khác nhau.
Xem cam kết c250e02 (28 tháng 11 năm 2017) của Ramsay Jones (``) .
Xem cam kết eb0ccfd , cam kết 78a6766 , cam kết f50e766 , cam kết abade65 (ngày 12 tháng 11 năm 2017) bởi brian m. carlson ( bk2204
) .
(Hợp nhất bởi Junio C Hamano - gitster
- in cam kết 721cc43 , ngày 13 tháng 12 năm 2017)
Thêm cấu trúc đại diện cho thuật toán băm
Vì trong tương lai, chúng tôi muốn hỗ trợ một thuật toán băm bổ sung, hãy thêm một cấu trúc đại diện cho một thuật toán băm và tất cả dữ liệu phải đi cùng với nó .
Thêm một hằng số để cho phép dễ dàng liệt kê các thuật toán băm .
Triển khai chức năngtypedefs
để tạo một API trừu tượng có thể được sử dụng bởi bất kỳ thuật toán băm nào và trình bao bọc cho các hàm SHA1 hiện có phù hợp với API này.Hiển thị giá trị cho kích thước hex cũng như kích thước nhị phân .
Trong khi một giá trị sẽ luôn gấp đôi giá trị kia, cả hai giá trị đều được sử dụng cực kỳ phổ biến trong toàn bộ codebase và cung cấp cả hai giá trị dẫn đến khả năng đọc được cải thiện.Không bao gồm mục nhập trong cấu trúc thuật toán băm cho ID đối tượng rỗng.
Vì giá trị này là tất cả các số không, nên mọi ID đối tượng bằng 0 có kích thước phù hợp đều có thể được sử dụng và không cần phải lưu trữ một ID nhất định trên cơ sở mỗi băm.Kế hoạch chuyển đổi hàm băm hiện tại hình dung thời điểm mà chúng tôi sẽ chấp nhận đầu vào từ người dùng có thể ở dạng SHA-1 hoặc ở định dạng NewHash.
Vì chúng tôi không thể biết người dùng đã cung cấp giá trị nào, hãy thêm một hằng số đại diện cho thuật toán chưa biết để cho phép chúng tôi chỉ ra rằng chúng tôi phải tra cứu giá trị chính xác.
Tích hợp hỗ trợ thuật toán băm với thiết lập repo
Trong các phiên bản tương lai của Git, chúng tôi có kế hoạch hỗ trợ thêm một thuật toán băm.
Tích hợp việc liệt kê các thuật toán băm với thiết lập kho lưu trữ và lưu trữ một con trỏ tới dữ liệu đã liệt kê trong kho lưu trữ cấu trúc .
Tất nhiên, chúng tôi hiện chỉ hỗ trợ SHA-1, vì vậy hãy mã hóa giá trị này vàoread_repository_format
.
Trong tương lai, chúng tôi sẽ liệt kê giá trị này từ cấu hình.Thêm một hằng số,
the_hash_algo
trỏ tớihash_algo
con trỏ cấu trúc trong toàn cục kho lưu trữ.
Lưu ý rằng đây là hàm băm được sử dụng để tuần tự hóa dữ liệu vào đĩa, không phải hàm băm được sử dụng để hiển thị các mục cho người dùng.
Kế hoạch chuyển đổi dự đoán rằng những điều này có thể khác nhau.
Chúng tôi có thể thêm một phần tử bổ sung trong tương lai (giả sửui_hash_algo
) để cung cấp cho trường hợp này.
Cập nhật tháng 8 năm 2018, đối với Git 2.19 (Quý 3 năm 2018), Git dường như chọn SHA-256 làm NewHash.
Xem cam kết 0ed8d8d (04/08/2018) của Jonathan Nieder ( artagnon
) .
Xem cam kết 13f5e09 (25 thg 7, 2018) bởi Ævar Arnfjörð Bjarmason ( avar
) .
(Merged bởi Junio C Hamano - gitster
- trong phạm 34f2297 , ngày 20 tháng 8 2018)
doc
hash-function-transition
: chọn SHA-256 làm NewHashTừ góc độ bảo mật, có vẻ như SHA-256, BLAKE2, SHA3-256, K12, v.v. đều được cho là có các thuộc tính bảo mật tương tự.
Tất cả đều là những lựa chọn tốt theo quan điểm bảo mật.SHA-256 có một số ưu điểm:
Nó đã xuất hiện được một thời gian, được sử dụng rộng rãi và được hỗ trợ bởi hầu hết mọi thư viện tiền điện tử (OpenSSL, mbedTLS, CryptoNG, SecureTransport, v.v.).
Khi bạn so sánh với SHA1DC, hầu hết các triển khai SHA-256 được vector hóa thực sự nhanh hơn, ngay cả khi không tăng tốc.
Nếu chúng ta đang thực hiện chữ ký với OpenPGP (hoặc thậm chí, tôi cho là CMS), chúng ta sẽ sử dụng SHA-2, vì vậy, việc bảo mật của chúng ta phụ thuộc vào hai thuật toán riêng biệt sẽ không hợp lý khi một trong hai thuật toán đó một mình có thể phá vỡ an ninh khi chúng ta chỉ có thể phụ thuộc vào một cái.
Vì vậy, nó là SHA-256 .
Cập nhật tài liệu thiết kế chuyển đổi hàm băm để nói như vậy.Sau bản vá này, không có trường hợp nào còn lại của chuỗi "
NewHash
", ngoại trừ việc sử dụng không liên quan từ năm 2008 làm tên biến trongt/t9700/test.pl
.
Bạn có thể thấy quá trình chuyển đổi này sang SHA 256 đang diễn ra với Git 2.20 (Q4 2018):
Xem cam kết 0d7c419 , cam kết dda6346 , cam kết eccb5a5 , cam kết 93eb00f , cam kết d8a3a69 , cam kết fbd0e37 , cam kết f690b6b , cam kết 49d1660 , cam kết 268babd , cam kết fa13080 , cam kết 7b5e614 , cam kết 58ce21b , cam kết 2f0c9e9 , cam kết 825544a (15 Tháng 10 2018) bởi brian m . carlson ( bk2204
) .
Xem cam kết 6afedba (15 tháng 10 năm 2018) bởi SZEDER Gábor ( szeder
) .
(Hợp nhất bởiJunio C Hamano - gitster
- trong phạm d829d49 , ngày 30 tháng 10 2018)
thay thế các hằng số được mã hóa cứng
Thay thế một số hằng số dựa trên 40 bằng các tham chiếu đến
GIT_MAX_HEXSZ
hoặcthe_hash_algo
, nếu thích hợp.
Chuyển đổi tất cả các cách sử dụngGIT_SHA1_HEXSZ
để sử dụngthe_hash_algo
sao cho chúng phù hợp với bất kỳ độ dài băm nào đã cho.
Thay vì sử dụng một hằng số được mã hóa cứng cho kích thước của ID đối tượng hex, hãy chuyển sang sử dụng con trỏ được tính toán từparse_oid_hex
các điểm đó sau ID đối tượng được phân tích cú pháp.
GIT_SHA1_HEXSZ
tiếp tục bị xóa / thay thế bằng Git 2.22 (Quý 2 năm 2019) và cam kết d4e568b .
Quá trình chuyển đổi đó tiếp tục với Git 2.21 (Q1 2019), bổ sung thêm hàm băm sha-256 và cắm nó qua mã để cho phép xây dựng Git với "NewHash".
Xem cam kết 4b4e291 , cam kết 27dc04c , cam kết 13eeedb , cam kết c166599 , cam kết 37649b7 , cam kết a2ce0a7 , cam kết 50c817e , cam kết 9a3a0ff , cam kết 0dab712 , cam kết 47edb64 (14 tháng 11 năm 2018) và cam kết 2f90b9d , cam kết 1ccf07c (22 tháng 10 năm 2018) bởi brian m . carlson ( bk2204
) .
(Hợp nhất bởi Junio C Hamano - gitster
- in commit 33e4ae9 , 29 Jan 2019)
Thêm triển khai cơ sở của hỗ trợ SHA-256 (tháng 2 năm 2019)
SHA-1 yếu và chúng ta cần chuyển sang một hàm băm mới.
Trong một thời gian, chúng tôi đã gọi chức năng mới này làNewHash
.
Gần đây, chúng tôi đã quyết định chọn SHA-256 làNewHash
.
Các lý do đằng sau sự lựa chọn SHA-256 được nêu trong chủ đề này và trong lịch sử cam kết cho tài liệu chuyển đổi hàm băm.Thêm triển khai cơ bản của SHA-256 dựa trên SHA-256
libtomcrypt
, nằm trong miền công cộng.
Tối ưu hóa nó và tái cấu trúc nó để đáp ứng các tiêu chuẩn mã hóa của chúng tôi.
Kéo cập nhật và các chức năng cuối cùng từ việc triển khai khối SHA-1, vì chúng ta biết các chức năng này chính xác với tất cả các trình biên dịch. Việc triển khai này chậm hơn SHA-1, nhưng các triển khai hiệu quả hơn sẽ được giới thiệu trong các cam kết trong tương lai.Nối SHA-256 trong danh sách các thuật toán băm và thêm một bài kiểm tra rằng thuật toán hoạt động chính xác.
Lưu ý rằng với bản vá này, vẫn không thể chuyển sang sử dụng SHA-256 trong Git.
Cần có các bản vá bổ sung để chuẩn bị mã để xử lý thuật toán băm lớn hơn và cần có các bản sửa lỗi kiểm tra thêm.
hash
: thêm triển khai SHA-256 bằng OpenSSLChúng tôi đã có sẵn các quy trình OpenSSL cho SHA-1, vì vậy hãy thêm các quy trình cho SHA-256.
Trên Core i7-6600U, triển khai SHA-256 này so sánh thuận lợi với triển khai SHA1DC SHA-1:
SHA-1: 157 MiB/s (64 byte chunks); 337 MiB/s (16 KiB chunks) SHA-256: 165 MiB/s (64 byte chunks); 408 MiB/s (16 KiB chunks)
sha256
: thêm một triển khai SHA-256 bằng cách sử dụnglibgcrypt
Nói chung, một trong những quy trình mật mã được viết trong assembly tốt hơn so với C và điều này cũng đúng với SHA-256.
Ngoài ra, hầu hết các bản phân phối Linux không thể phân phối Git được liên kết với OpenSSL vì lý do cấp phép.Hầu hết các hệ thống với GnuPG cũng sẽ có
libgcrypt
, vì nó là phụ thuộc của GnuPG.
libgcrypt
cũng nhanh hơn so với việc triển khai SHA1DC cho các thông báo có kích thước ít KiB trở lên.Để so sánh, trên Core i7-6600U, việc triển khai này xử lý 16 khối KiB với tốc độ 355 MiB / giây trong khi SHA1DC xử lý các khối tương đương ở tốc độ 337 MiB / s.
Ngoài ra, libgcrypt được cấp phép theo LGPL 2.1, tương thích với GPL. Thêm một triển khai SHA-256 sử dụng libgcrypt.
Nỗ lực nâng cấp tiếp tục với Git 2.24 (Q4 2019)
Xem cam kết aaa95df , cam kết be8e172 , cam kết 3f34d70 , cam kết fc06be3 , cam kết 69fa337 , cam kết 3a4d7aa , cam kết e0cb7cd , cam kết 8d4d86b , cam kết f6ca67d , cam kết dd336a5 , cam kết 894c0f6 , cam kết 4439c7a , cam kết 95518fa , cam kết e84f357 , cam kết fe9fec4 , cam kết 976ff7e , cam kết 703d2d4 , cam kết 9d958cc , cam kết 7962e04 , phí cam kết4930(18 tháng 8, 2019) bởi brian m. carlson ( bk2204
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- in cam kết 676278f , ngày 11 tháng 10 năm 2019)
Thay vì sử dụng
GIT_SHA1_HEXSZ
và các hằng số được mã hóa cứng, hãy chuyển sang sử dụngthe_hash_algo
.
Với Git 2.26 (Q1 2020), các tập lệnh thử nghiệm đã sẵn sàng cho ngày tên đối tượng sẽ sử dụng SHA-256.
Xem cam kết 277eb5a , cam kết 44b6c05 , cam kết 7a868c5 , cam kết 1b8f39f , cam kết a8c17e3 , cam 8.320.722 , cam kết 74ad99b , cam kết ba1be1a , cam kết cba472d , cam kết 82d5aeb , cam kết 3c5e65c , cam kết 235d3cd , cam kết 1d86c8f , cam kết 525a7f1 , cam kết 7a1bcb2 , cam kết cb78f4f , cam kết 717c939 , cam kết 08a9dd8 , cam kết 215b60b , cam kết 194264c(21 tháng 12, 2019) bởi brian m. carlson ( bk2204
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- in commit f52ab33 , 05 Feb 2020)
Thí dụ:
t4204
: làm cho kích thước băm độc lậpNgười ký tên: brian m. carlson
Sử dụng
$OID_REGEX
thay cho biểu thức chính quy được mã hóa cứng.
Vì vậy, thay vì sử dụng:
grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output
Các thử nghiệm đang sử dụng
grep "^$OID_REGEX $(git rev-parse HEAD)$" output
Và OID_REGEX
đến từ cam kết bdee9cd (13 tháng 5 năm 2018) bởi brian m. carlson ( bk2204
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 9472b13 , ngày 30 tháng 5 năm 2018, Git v2.18.0-rc0)
t/test-lib
: giới thiệuOID_REGEX
Người ký tên: brian m. carlson
Hiện tại, chúng tôi có một biến
$_x40,
chứa regex khớp với hằng số hex đầy đủ 40 ký tự.Tuy nhiên, với
NewHash
, chúng tôi sẽ có ID đối tượng dài hơn 40 ký tự.Trong trường hợp như vậy,
$_x40
sẽ là một cái tên khó hiểu.Tạo một
$OID_REGEX
biến sẽ luôn phản ánh một regex khớp với ID đối tượng thích hợp, bất kể độ dài của hàm băm hiện tại.
Và, vẫn còn để thử nghiệm:
Xem cam kết f303765 , cam kết edf0424 , cam kết 5db24dc , cam kết d341e08 , cam kết 88ed241 , cam kết 48c10cc , cam kết f7ae8e6 , cam kết e70649b , cam kết a30f93b , cam kết a79eec2 , cam kết 796d138 , cam kết 417e45e , cam kết dfa5f53 , cam kết f743e8f , cam kết 72f936b , cam kết 5df0f11 , cam kết 07877f3 , cam kết 6025e89 , cam kết 7b1a182 , cam kết 94db7e3 ,cam kết db12505 (07/02/2020) bởi brian m. carlson ( bk2204
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 5af345a , ngày 17 tháng 2 năm 2020)
t5703
: làm cho thử nghiệm hoạt động với SHA-256Người ký tên: brian m. carlson
Thử nghiệm này sử dụng ID đối tượng có độ dài 40 ký tự hex, khiến thử nghiệm không những không vượt qua mà còn bị treo khi chạy với SHA-256 dưới dạng băm.
Thay đổi giá trị này thành ID đối tượng giả cố định bằng cách sử dụng
test_oid_init
vàtest_oid
.Hơn nữa, hãy đảm bảo rằng chúng tôi trích xuất ID đối tượng có độ dài thích hợp bằng cách sử dụng cắt với các trường thay vì độ dài cố định.
Một số codepath đã được cung cấp một cá thể kho lưu trữ như là một tham số để hoạt động trong kho lưu trữ, nhưng đã chuyển the_repository
thể hiện cho các callees của nó, đã được dọn dẹp (phần nào) với Git 2.26 (Q1 2020).
Xem cam kết b98d188 , cam kết 2dcde20 , cam kết 7ad5c44 , cam kết c8123e7 , cam kết 5ec9b8a , cam kết a651946 , cam kết eb999b3 (30 tháng 1 năm 2020) bởi Matheus Tavares ( matheustavares
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 78e67cd , ngày 14 tháng 2 năm 2020)
sha1-file
: cho phépcheck_object_signature()
xử lý bất kỳ repo nàoNgười ký hợp đồng: Matheus Tavares
Một số người gọi
check_object_signature()
có thể hoạt động trên các kho lưu trữ tùy ý, nhưng kho lưu trữ không được chuyển tới hàm này. Thay vào đó,the_repository
luôn được sử dụng trong nội bộ.
Để khắc phục sự mâu thuẫn có thể xảy ra, hãy cho phép hàm nhận một kho lưu trữ cấu trúc và yêu cầu những người gọi đó chuyển kho lưu trữ đang được xử lý.
Dựa trên:
sha1-file
: Passgit_hash_algo
đểhash_object_file()
Người ký hợp đồng: Matheus Tavares
Cho phép
hash_object_file()
làm việc trên các repo tùy ý bằng cách giới thiệu mộtgit_hash_algo
tham số. Thay đổi người gọi có con trỏ kho lưu trữ cấu trúc trong phạm vi của họ để chuyểngit_hash_algo
từ kho đã nói.
Đối với tất cả những người gọi khác, hãy chuyển sangthe_hash_algo
, đã được sử dụng nội bộ tạihash_object_file()
.
Chức năng này sẽ được sử dụng trong bản vá sau đểcheck_object_signature()
có thể hoạt động trên các repo tùy ý (do đó, sẽ được sử dụng để khắc phục sự không nhất quán tạiobject.c
: parse_object ()).
git rev-parse
bây giờ có thể in những gì băm sẽ được sử dụng: stackoverflow.com/a/58862319/6309 . Và cây trống có id SHA2 mới: stackoverflow.com/a/9766506/6309
CẬP NHẬT : Câu hỏi trên và câu trả lời này là từ năm 2015. Kể từ đó, Google đã công bố vụ va chạm SHA-1 đầu tiên: https://security.googleblog.com/2017/02/annocting-first-sha1-collision.html
Rõ ràng là tôi chỉ có thể suy đoán từ bên ngoài nhìn vào lý do tại sao Git tiếp tục sử dụng SHA-1, nhưng đây có thể là một trong những lý do:
unsigned char[20]
bộ đệm được mã hóa cứng đó ở khắp nơi ;-), việc lập trình cho sự linh hoạt của mật mã dễ dàng hơn rất nhiều khi bắt đầu, thay vì trang bị thêm sau đó.Một số liên kết:
Quan điểm cá nhân của tôi sẽ là trong khi các cuộc tấn công thực tế có thể sẽ mất một thời gian, và ngay cả khi chúng xảy ra, mọi người có thể sẽ giảm nhẹ chúng ban đầu bằng các phương tiện khác ngoài việc thay đổi chính thuật toán băm, rằng nếu bạn quan tâm đến bảo mật, bạn sẽ mắc lỗi về mặt thận trọng với các lựa chọn thuật toán của bạn và liên tục sửa đổi nâng cao sức mạnh bảo mật của bạn, bởi vì khả năng của những kẻ tấn công cũng chỉ đi theo một hướng, vì vậy sẽ không khôn ngoan nếu lấy Git làm hình mẫu, đặc biệt là mục đích của nó trong sử dụng SHA-1 không nhằm mục đích bảo mật mật mã.
Đây là cuộc thảo luận về tính cấp thiết của việc di chuyển khỏi SHA1 đối với Mercurial, nhưng nó cũng áp dụng cho Git: https://www.mercurial-scm.org/wiki/mpm/SHA1
Tóm lại: Nếu hôm nay bạn không cực kỳ thận trọng, bạn có nhiều lỗ hổng nghiêm trọng hơn sha1. Nhưng bất chấp điều đó, Mercurial đã bắt đầu hơn 10 năm trước để chuẩn bị di cư khỏi sha1.
công việc đã được tiến hành trong nhiều năm để trang bị thêm cấu trúc dữ liệu và giao thức của Mercurial cho những người kế nhiệm SHA1. Không gian lưu trữ đã được phân bổ cho các hàm băm lớn hơn trong cấu trúc nhật ký sửa đổi của chúng tôi hơn 10 năm trước trong Mercurial 0.9 với sự ra đời của RevlogNG. Định dạng gói2 được giới thiệu gần đây hỗ trợ việc trao đổi các loại băm khác nhau qua mạng. Phần còn lại duy nhất là lựa chọn chức năng thay thế và chọn chiến lược tương thích ngược.
Nếu git không di chuyển khỏi sha1 trước khi Mercurial thực hiện, bạn luôn có thể thêm một mức bảo mật khác bằng cách giữ một nhân bản Mercurial cục bộ với hg-git .
Hiện có một kế hoạch chuyển đổi sang một hàm băm mạnh hơn, vì vậy có vẻ như trong tương lai nó sẽ sử dụng một hàm băm hiện đại hơn SHA-1. Từ kế hoạch chuyển đổi hiện tại :
Một số hàm băm đang được xem xét là SHA-256, SHA-512/256, SHA-256x16, K12 và BLAKE2bp-256