Tôi đang phát triển ứng dụng web ASP.NET sử dụng HttpWebRequest để gửi yêu cầu đến máy chủ khác. Nó gửi yêu cầu qua HTTPS và máy chủ từ xa yêu cầu chứng chỉ ứng dụng khách. Yêu cầu không thành công trong ứng dụng .NET, dường như không thể gửi đúng chứng chỉ ứng dụng khách. Nếu tôi chỉ truy cập url bằng trình duyệt web (dành riêng cho Chrome), tôi có thể kết nối và gửi thành công chứng chỉ ứng dụng khách.
Mã bên dưới là một bản sao đơn giản, chỉ có một yêu cầu GET cơ bản.
var r = WebRequest.Create(url) as HttpWebRequest;
r.ClientCertificates = X509CertificateCollection mới { myX509Cert };
sử dụng (var resp = r.GetResponse() as HttpWebResponse) {
...
}
Tôi nhận được ngoại lệ yêu thích của chúng tôi là "Không thể tạo kênh bảo mật SSL/TLS". Thông thường, những loại sự cố này liên quan đến vấn đề liên quan đến quyền khóa riêng của chứng chỉ. Tôi đã cố gắng hết sức để đảm bảo mọi thứ được cấu hình chính xác nhưng có thể tôi đã bỏ sót điều gì đó. Tóm lại, máy chủ từ xa đang gửi TLS
Yêu cầu chứng chỉ
, với một danh sách có vẻ nhận dạng chính xác chứng chỉ ứng dụng khách của tôi nhưng ứng dụng của tôi không phản hồi với bất kỳ chứng chỉ ứng dụng khách nào.
Đây là thiết lập của tôi:
Windows 7 Professional 64-bit
Có thể tái tạo trong ứng dụng ASP.NET MVC 3/.NET 4 chạy trong Visual Studio Development Server, ứng dụng ASP.NET WebForms/.NET 3.5 chạy trong IIS cục bộ và .NET Console Application/.NET Câu hỏi 4
Microsoft .NET Framework 4.5 đã được cài đặt gần đây. Chưa kiểm tra xem đây có phải là vấn đề không
Đây là tất cả những gì tôi đã thử và những gì tôi biết:
Mã này có vẻ hoạt động tốt khi chạy trên máy Windows XP
Tôi đảm bảo rằng chứng chỉ ứng dụng khách của tôi đã được nhập vào kho "Chứng chỉ cá nhân" của máy cục bộ và các quyền "Khóa riêng" đã được định cấu hình chính xác cho tôi và tất cả người dùng IIS có liên quan
Tôi đã thử cài đặt lại chứng chỉ trên máy tính của mình nhiều lần
Tôi đã xác nhận rằng ứng dụng .NET có thể truy cập chứng chỉ X509 vàHasPrivateKey
= đúng
Đảm bảo chứng chỉ ứng dụng khách của tôi hợp lệ. Trên thực tế, đây là những gì sẽ được chạy trênChứng chỉ SSL cho máy chủ web của bạn
Tôi đặt nó trong đối tượng yêu cầuXác thực trước=true
. không có tác động
Tôi cố gắng thiết lập ServicePointManager.Expect100Continue = false
,Phảikhông có tác động
Tôi cố gắng thiết lậpServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
, nhưng rõ ràng máy chủ từ xa yêu cầu TLS, vì vậy đối vớikhông hữu ích
Tôi sẽServicePointManager.ServerCertificateValidationCallback
Đại biểu được đặt thành luôn trả về đúng. Nhưng yêu cầu không thành công sớm hơn nhiều trong quá trình bắt tay TLS, trước khi nó đạt đến điểm mà đại biểu này được gọiđến mức
Khi tôi truy cập URL trong Chrome, nó sẽ hỏi tôi chứng chỉ ứng dụng khách, cung cấp chứng chỉ ứng dụng khách chính xác làm lựa chọn, sau đó chọn chứng chỉ đó và tôi nhận được phản hồi hợp lệ. Khi tôi tạo yêu cầu trong Fiddler, nó cũng hoạt động tốt. Vì vậy, đây chắc chắn là sự cố cụ thể đối với mã .NET của tôi chứ không phải bản thân chứng chỉ hoặc máy chủ từ xa, v.v.
Nhà cung cấp mà tôi đang làm việc cùng có cùng một dịch vụ được thiết lập trên một máy chủ từ xa khác và dịch vụ này yêu cầu chứng chỉ ứng dụng khách khác. Vì vậy, tôi đã thử điều tương tự với một URL và chứng chỉ ứng dụng khách khác và gặp lỗi tương tự
tôi đã thêm
Dấu vết System.Netvà thấy:
SecureChannel#26717201 - Chúng tôi có chứng chỉ do người dùng cung cấp. Máy chủ đã chỉ định 6 nhà phát hành. Đang tìm kiếm chứng chỉ phù hợp với bất kỳ nhà phát hành nào.
SecureChannel#26717201 - Còn lại 0 chứng chỉ ứng dụng khách để lựa chọn.
...
Khởi tạoSecurityContext(Số lượng trong bộ đệm=2, Độ dài bộ đệm ngoài=0, mã trả về=CertUnknown).
Tôi đã kích hoạt đầy đủ
ghi nhật ký KÊNHvà xem cảnh báo sau:
Máy chủ từ xa đã yêu cầu xác thực ứng dụng khách SSL nhưng không tìm thấy chứng chỉ ứng dụng khách phù hợp. Yêu cầu kết nối SSL này có thể thành công hoặc thất bại, tùy thuộc vào cài đặt chính sách của máy chủ.
Tôi chạy Wireshark và thấy rằng máy chủ từ xa đã gửi một
Yêu cầu chứng chỉ
, nó dường như có một
Tên phân biệt
mục nhập chỉ định chính xác giá trị CN\OU\O của chứng chỉ ứng dụng khách của tôi. Sau đó, ứng dụng của tôi gửi phản hồi chứng chỉ mà không có chứng chỉ.
Có vẻ như tôi chưa thiết lập chứng chỉ này để hoạt động bình thường với các ứng dụng .NET trong Windows 7. Dự đoán tốt nhất của tôi là có điều gì đó khác biệt giữa máy Windows 7 mới so với máy XP hiện đang khiến nó bị lỗi. Hiện tại tôi không thể xác nhận bằng môi trường Windows XP. Tôi sẽ mất vài ngày, nhưng tôi thực sự muốn giải quyết vấn đề này càng sớm càng tốt.
Bất kỳ ý tưởng sẽ được đánh giá rất cao. Cảm ơn!
biên tậpNhư đã đề cập ở trên, khi kết nối với URL trong Chrome, trình duyệt sẽ yêu cầu tôi cung cấp chứng chỉ ứng dụng khách và tôi có thể cung cấp chứng chỉ chính xác và kết nối thành công. Tuy nhiên, tôi không thể thực hiện thành công việc này trong Internet Explorer (9). Tôi chỉ nhận được thông báo "Internet Explorer không thể hiển thị trang web" mà không có lời nhắc hoặc lời giải thích nào khác. Ai đó đã nói với tôi điều này có thể có liên quan bởi vì
WebRequest.Tạo
Có hành vi tương tự như IE. Tôi đang nghiên cứu xem điều này có nghĩa là gì nhưng sẽ đánh giá cao mọi suy nghĩ về điều này.
biên tậpNgoài ra, tôi cần lưu ý rằng máy chủ từ xa sử dụng chứng chỉ SSL tự ký. Ban đầu tôi nghĩ đó có thể là vấn đề nên tôi đã thêm chứng chỉ làm gốc đáng tin cậy trong MMC để chứng chỉ hiển thị hợp lệ trên máy tính của tôi. Điều này không giải quyết được vấn đề.
Hóa ra đây là một vấn đề khá đơn giản nhưng lại khó phát hiện. Máy chủ từ xa nơi đặt ứng dụng của tôi có chứng chỉ ứng dụng khách của tôi trong kho khóa, nhưng chứng chỉ ứng dụng khách của tôi không có bất kỳ chứng chỉ gốc nào trong chuỗi tin cậy của nó.
Tôi có thể sử dụng mã của mình để gửi thành công yêu cầu đến các máy chủ khác yêu cầu chứng chỉ ứng dụng khách. Tôi đã ghi lại trong Wireshark thời điểm yêu cầu thành công này được gửi và cả khi yêu cầu không thành công được gửi đến một máy chủ khác. Trong quá trình chụp Wireshark, tôi tìm thấy "Xin chào máy chủ" và so sánh tin nhắn được gửi từ máy chủ từ xa. Máy chủ từ xa "tốt" đang gửi chứng chỉ ứng dụng khách của tôi cùng với chứng chỉ gốc trong phần "Yêu cầu chứng chỉ" của tin nhắn. Máy chủ từ xa "bị lỗi" chỉ gửi chứng chỉ ứng dụng khách của tôi.
Điều này làm tôi nhớ đến dấu vết chẩn đoán System.Net hiển thị "Máy chủ đã chỉ định 6 nhà phát hành... còn lại 0 chứng chỉ ứng dụng khách để chọn". Vì vậy, hóa ra "nhà phát hành" là thuật ngữ chính ở đây. Lúc đầu, thật dễ dàng để bỏ qua vì trong phân tích ban đầu của tôi về bắt tay TLS, máy chủ đã gửi chứng chỉ ứng dụng khách của tôi trong yêu cầu chứng chỉ. Nhìn nhận lại, điều hợp lý là máy chủ lẽ ra phải gửi chứng chỉ gốc của bạn chứ không phải chính chứng chỉ ứng dụng khách.
Tôi là một lập trình viên xuất sắc, rất giỏi!