Tôi luôn hiểu mục đích của việc ký một bản lắp ráp là kiểm tra thời gian chạy để đảm bảo rằng việc nâng cấp mã đến từ một nguồn đáng tin cậy. Có hiệu quả họ đang cố gắng tránh loại tình huống này:
Tôi mua thư viện mã hóa từ Công ty A, ngay sau đó Công ty B nắm giữ chi tiết email của tôi và gửi cho tôi bản nâng cấp miễn phí lên hội đồng giả vờ là lỗi bảo mật chính sửa chữa từ công ty A khi nó thực sự tiêm một phương thức ẩn vào mã của tôi để gửi tất cả dữ liệu mà tôi đang cố mã hóa cho các máy chủ của công ty B. Giả sử rằng tôi là một thằng ngốc và mù quáng thêm dll mới này vào thư mục bin của ứng dụng của tôi thực tế là điều này không được ký với cùng khóa riêng vì phiên bản cũ sẽ được chọn trong thời gian chạy gây ra một ngoại lệ và bảo vệ dữ liệu của tôi. Vì vậy, tôi thấy không có lý do gì mà bạn sẽ xuất bản khóa công khai bên ngoài assembly vì nó không phải đảm bảo rằng tệp gốc xuất phát từ một nhà cung cấp cụ thể, chỉ tất cả các phiên bản tiếp theo đến từ cùng một nơi đầu tiên.
Wikipedia nói nhiều điều tương tự (chỉ với ít từ hơn đáng kể).
Edited để thêm thêm thông tin trong một nỗ lực để làm điều này rõ ràng hơn ...
Tôi nghĩ rằng điều đó cần phải được làm rõ đầu tiên là các cặp khóa công cộng và tư nhân là duy nhất. Điều đó có nghĩa rằng việc biết khóa công khai không đủ thông tin để xây dựng lại assembly theo cách nó sẽ vượt qua các kiểm tra hash giống nhau.
Vì vậy, người dùng Z đang sử dụng thư viện mã hóa từ Công ty A nằm trong thư mục bin của ứng dụng. Để thực hiện điều này, ông là tham khảo các DLL như sau:
Encryption, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07"
Mục đích của khóa công khai là cung cấp cho chúng tôi với three benefits mà tôi sẽ xử lý cùng một lúc. Đầu tiên, nó cung cấp một tên duy nhất cho việc lắp ráp - điều này mang lại cho chúng tôi không có bảo mật bổ sung nhưng không dừng C phong cách dll Địa ngục nơi hai công ty khác nhau có thể phát hành hai thư viện khác nhau được gọi là Encyption phiên bản 1.0.0.0 và bạn sẽ không thể để lưu trữ chúng trong cùng một thư mục vì không có cách nào để phân biệt chúng.
Thứ hai, nó ngăn chặn trường hợp mà tôi đã nêu trong bài đăng gốc của mình. Công ty B không thể tạo phiên bản Thư viện mã hóa khác cũng là phiên bản 1.0.0.0 và có cùng khóa công khai (để toàn bộ tên sẽ khớp và bạn sẽ gọi mã của họ thay vì Công ty A). Họ không thể làm điều này bởi vì nếu khóa công khai của họ phù hợp thì khóa riêng tư cũng phải khớp (vì mỗi cặp là duy nhất). Cách duy nhất họ có thể nhận được khóa riêng để phù hợp là bằng cách ảnh hưởng đến an ninh của Công ty A.
Cuối cùng, nó đảm bảo tính toàn vẹn của tệp (hoặc thay đổi thông qua tiêm tham nhũng hoặc mã độc). Các dll được băm tại thời gian chạy (khi nó là tư nhân và trong thư mục bin của ứng dụng) hoặc cài đặt thời gian (khi bạn đặt nó trong GAC) bằng cách sử dụng khóa công khai và băm đó được so sánh với băm được encrpyted bởi tư nhân và được lưu trữ trong hội đồng. This page có một số biểu đồ và các chi tiết khác. Một lần nữa cách duy nhất để giả mạo băm này là để biết khóa riêng.
Vì vậy, để trình bày kịch bản cụ thể mà tôi đã mô tả ở trên, giả sử rằng Công ty B đang cố gắng cung cấp cho User Z phiên bản độc hại của tệp mã hóa. Nỗ lực đầu tiên của tôi là chỉ cần tạo dll của riêng tôi với tên Mã hóa và Phiên bản 1.0.0.0 và ký tên bằng cặp khóa của riêng tôi. Rất tiếc, tôi không thể thay đổi mã tham chiếu trong ứng dụng của Người dùng Z để nó không thể kiểm tra tên đầy đủ và không được tải. "Được rồi," tôi nói trong khi xoay bộ ria mép của mình, "Tôi sẽ đơn giản thay đổi chìa khóa công khai của hội đồng của tôi để phù hợp với công ty A". Khi đã thực hiện xong việc kiểm tra tên, nhưng việc kiểm tra hash sẽ thất bại vì ứng dụng của User Z sẽ không thể giải mã hash được lưu trữ trong assembly (được mã hóa bằng khóa riêng của Công ty B) với khóa công khai (Company A) đã được cung cấp. Do đó, cách duy nhất để Công ty B tạo ra một thư viện giả vờ là Công ty A là biết khóa riêng của Công ty A. Không có kiểm tra bảo mật nào phụ thuộc vào Công ty A xuất bản khóa công khai ở bất kỳ nơi nào khác ngoài bản phát hành ban đầu của hội đồng. Lưu ý rằng tất cả các tính năng này không đảm bảo (và không yêu cầu đảm bảo) rằng lắp ráp ban đầu đến từ Công ty A, được xử lý bởi các hệ thống khác như Verisign hoặc dịch vụ Authenticode của Microsoft, chúng chỉ đảm bảo rằng một khi bạn đã tham khảo hội đồng chỉ có Công ty A mới có thể thực hiện các thay đổi đối với mã đó.
Điều đó hoàn toàn không rõ ràng và không được đề cập trong bài viết được liên kết một cách rõ ràng.Để thực hiện tất cả điều này, thời gian chạy cần phải lưu trữ bộ nhớ đệm của mỗi và mọi assembly và xác minh rằng khi nạp assembly. Liệu nó thực sự làm điều này? – sharptooth
Theo "CLR thông qua C#" của Jeffery Richter nó làm khi lắp ráp không có trong GAC. Trích dẫn từ cuốn sách: "Khi các assembly được đặt tên mạnh được nạp từ một vị trí khác với GAC, CLR so sánh các giá trị băm khi assembly được nạp. Nói cách khác, một hash của tập tin được thực hiện mỗi khi một ứng dụng thực thi và nạp assembly Hiệu suất này là một sự cân bằng để chắc chắn rằng nội dung của tập tin lắp ráp đã không bị giả mạo. " –
Tôi cũng sẽ thêm trích dẫn này từ "C# thông qua CLR" (sách được khuyến nghị cao): "Quan trọng: Cơ chế này chỉ đảm bảo rằng nội dung của tệp không bị giả mạo. Cơ chế không cho phép bạn cho biết nhà xuất bản là ai trừ khi bạn hoàn toàn lạc quan rằng nhà xuất bản đã tạo khóa công khai mà bạn có và bạn chắc chắn rằng khóa riêng của nhà xuất bản không bao giờ bị xâm phạm. " Vì vậy, ngay cả khi họ xuất bản khóa công khai tách biệt khỏi hội đồng, nó vẫn không thực sự cho phép bạn xác minh nhà xuất bản. –