Cách giải quyết không thể thiết lập mối quan hệ tin cậy cho kênh bảo mật SSL / TLS với quyền hạn


135

Thực sự nghĩ rằng tôi đã khắc phục vấn đề này, nhưng nó chỉ được ngụy trang trước đó.

Tôi có dịch vụ WCF được lưu trữ trong IIS 7 bằng HTTPS. Khi tôi duyệt đến trang web này trong Internet Explorer, nó hoạt động như một bùa mê, điều này là do tôi đã thêm chứng chỉ vào cửa hàng ủy quyền chứng chỉ gốc cục bộ.

Tôi đang phát triển trên 1 máy, vì vậy máy khách và máy chủ là cùng một máy. Chứng chỉ được tự ký trực tiếp từ quản lý IIS 7.

Tôi liên tục nhận được lỗi này bây giờ ...

Không thể thiết lập mối quan hệ tin cậy cho kênh bảo mật SSL / TLS có thẩm quyền.

... khi được gọi từ bảng điều khiển máy khách.

Tôi tự cấp cho mình quyền và dịch vụ mạng cho chứng chỉ, sử dụng findprivatekeyvà sử dụngcacls.exe .

Tôi đã cố gắng kết nối với dịch vụ bằng SOAPUI và nó hoạt động, vì vậy nó phải là một vấn đề trong ứng dụng khách của tôi, đó là mã dựa trên những gì được sử dụng để làm việc với http.

Nơi nào khác tôi có thể nhìn tôi dường như đã cạn kiệt tất cả các khả năng về lý do tại sao tôi không thể kết nối?



Nếu bạn có quyền kiểm soát việc tạo chứng chỉ, đừng quên "Tên chủ đề thay thế". Giống như bạn có thể đặt một thẻ hoang dã vào "* .full.domainname.com". Xem digicert.com/subject-alternative-name.htm
granadaCoder

Câu trả lời:


198

Là một workaround bạn có thể thêm một handler cho sự ServicePointManager's ServerCertificateValidationCallbacktrên các mặt hàng:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
    (se, cert, chain, sslerror) =>
        {
            return true;
        };

nhưng lưu ý rằng đây không phải là một thông lệ tốt vì nó hoàn toàn bỏ qua chứng chỉ máy chủ và nói với người quản lý điểm dịch vụ rằng bất kỳ chứng chỉ nào đều ổn có thể ảnh hưởng nghiêm trọng đến bảo mật của khách hàng. Bạn có thể tinh chỉnh điều này và thực hiện một số kiểm tra tùy chỉnh (đối với tên chứng chỉ, hàm băm, v.v.). ít nhất bạn có thể tránh được các vấn đề trong quá trình phát triển khi sử dụng chứng chỉ kiểm tra.


9
Tôi nghĩ rằng hầu hết các thiết lập công khai sẽ sử dụng chứng chỉ đã mua nhưng trong quá trình phát triển sử dụng mã trên trong các câu lệnh #if có điều kiện. Các nhà phát triển doanh nghiệp thường nên thiết lập một máy chủ CA nội bộ >> technet.microsoft.com/en-us/l
Library / cc875810.aspx

2
Đã giúp tôi tìm ra cách để cuộc gọi SSL WCF của tôi hoạt động với Fiddler2 để gỡ lỗi.
Roger Willcocks

2
@karank Cân nhắc đưa nó vào phương thức Application_Start trong Global.asax (xem stackoverflow.com/a/12507094/1175419 ). Tôi thực sự khuyên bạn nên sử dụng chỉ thị trình biên dịch #if DEBUG hoặc một cái gì đó tương tự như được đề cập trong nhận xét của Luke.
Giàu C

4
Tuyệt vời! bạn có thể sử dụng biểu thức lambda như System.Net.ServicePointManager.ServerCert veValidationCallback + = (se, cert, chain, sslerror) => true;
Dhanuka777

Một lời giải thích thêm có thể được tìm thấy ở đây: blog.effectivemessaging.com/2015_09_01_archive.html
granadaCoder

40

Khi tôi gặp vấn đề này là do client.config có các điểm cuối như:

 https://myserver/myservice.svc 

nhưng chứng chỉ đã được mong đợi

 https://myserver.mydomain.com/myservice.svc

Thay đổi điểm cuối để phù hợp với FQDN của máy chủ sẽ giải quyết vấn đề của tôi. Tôi biết đây không phải là nguyên nhân duy nhất của vấn đề này.


Tôi chỉ gặp vấn đề này một lần nữa và lần này nó đã xảy ra với chứng chỉ sai được sử dụng. Có vẻ như trong cả hai trường hợp, nó phải làm với việc ghép đúng tên.
Mike Cheel

3
Cấu hình được tạo tự động của tôi đã <endpoint address = " localhost / myservice.svc " thay đổi điều này thành <endpoint address = " mymachine.mydoman.com/myservice.svc " đã giải quyết vấn đề này.
hiệp sĩ

Đây hoàn toàn là vấn đề của tôi và tôi đã mất hai ngày để tìm câu trả lời của bạn. +1, tôi sẽ cung cấp cho bạn +1000 nếu tôi có thể.
AussieJoe

20

hai cái đầu tiên sử dụng lambda, cái thứ ba sử dụng mã thông thường ... hy vọng bạn thấy nó hữu ích

            //Trust all certificates
            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                ((sender, certificate, chain, sslPolicyErrors) => true);

            // trust sender
            System.Net.ServicePointManager.ServerCertificateValidationCallback
                = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));

            // validate cert by calling a function
            ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

    // callback used to validate the certificate in an SSL conversation
    private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
    {
        bool result = false;
        if (cert.Subject.ToUpper().Contains("YourServerName"))
        {
            result = true;
        }

        return result;
    }

1
// Tin tưởng tất cả các chứng chỉ System.Net.ServicePointManager.ServerCertertValidationCallback + = (se, cert, chain, sslerror) => {return true; }; // người gửi tin cậy System.Net.ServicePointManager.ServerCertertValidationCallback + = (se, cert, chain, sslerror) => {return cert.Subject.Contains ("ca-l-9wfvrm1.ceridian.ca"); };
VoodooChild

1
Bất kỳ cracker nào cũng có thể giả mạo chứng chỉ vượt qua tất cả các bài kiểm tra trên. Điều này là không an toàn.
Bjartur Thorlacius

19

Vấn đề của bạn phát sinh do bạn đang sử dụng khóa tự ký. Khách hàng không tin tưởng khóa này, bản thân khóa cũng không cung cấp chuỗi để xác thực hoặc danh sách hủy bỏ chứng chỉ.

Bạn có một vài lựa chọn - bạn có thể

  1. tắt xác nhận chứng chỉ trên máy khách (di chuyển xấu, người đàn ông ở giữa tấn công rất nhiều)

  2. sử dụng makecert để tạo CA gốc và tạo chứng chỉ từ đó (di chuyển ok, nhưng vẫn không có CRL)

  3. tạo một CA gốc nội bộ bằng Windows Chứng chỉ máy chủ hoặc giải pháp PKI khác sau đó tin tưởng chứng chỉ gốc đó (một chút khó khăn để quản lý)

  4. mua chứng chỉ SSL từ một trong những CA đáng tin cậy (đắt tiền)


3
Về (4), StartSSL thực sự sẽ cung cấp cho bạn chứng chỉ Lớp 1 miễn phí hoạt động trong tất cả các trình duyệt chính. Chúng hoạt động rất tốt cho tôi cho nửa tá trang web băng thông thấp.
psychboom

Tôi nghĩ rằng số 2 trong danh sách này ... url này có thể giúp ích: blog.technet.microsoft.com/jhoward/2005/02/02/ "Cách sử dụng MakeCert cho cơ quan chứng nhận gốc đáng tin cậy và cấp chứng chỉ SSL"
granadaCoder

1
Lưu ý: StartCom không còn đáng tin cậy nữa - và vừa bị xóa khỏi Chrome en.wikipedia.org/wiki/StartCom
Simon_Weaver

16

Một giải pháp một dòng. Thêm phần này vào bất cứ đâu trước khi gọi máy chủ ở phía máy khách:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };

Điều này chỉ nên được sử dụng cho mục đích thử nghiệm vì khách hàng sẽ bỏ qua kiểm tra bảo mật SSL / TLS.


2
Một cách giải quyết tuyệt vời để thử nghiệm. Chúng tôi đang tiêu thụ một dịch vụ mà nhà cung cấp đã biến an ninh thành một địa ngục sống với một chuỗi chứng chỉ bảo mật phức tạp và cho đến khi chúng tôi có thể có được các loại ngũ cốc và chuỗi hoạt động tốt, thì cách giải quyết này là điều duy nhất cho phép chúng tôi tiếp tục phát triển.
markaaronky

12

Tôi gặp phải cùng một vấn đề và tôi đã có thể giải quyết bằng hai giải pháp: Thứ nhất, tôi đã sử dụng "Chứng chỉ" đính kèm MMC cho "Tài khoản máy tính" và kéo chứng chỉ tự ký vào thư mục "Cơ quan chứng nhận gốc đáng tin cậy" . Điều này có nghĩa là máy tính cục bộ (máy tính đã tạo chứng chỉ) giờ sẽ tin tưởng chứng chỉ đó. Thứ hai, tôi nhận thấy rằng chứng chỉ được tạo cho một số tên máy tính nội bộ, nhưng dịch vụ web đã được truy cập bằng tên khác. Điều này gây ra sự không phù hợp khi xác nhận giấy chứng nhận. Chúng tôi đã tạo chứng chỉ cho computer.operations.local, nhưng đã truy cập dịch vụ web bằng cách sử dụng https://computer.i INTERNaldomain.companydomain.com . Khi chúng tôi chuyển URL sang một được sử dụng để tạo chứng chỉ, chúng tôi không gặp phải lỗi nào nữa.

Có thể chỉ cần chuyển đổi URL sẽ có hiệu quả, nhưng bằng cách làm cho chứng chỉ được tin cậy, bạn cũng tránh được màn hình màu đỏ trong Internet Explorer, nơi nó cho bạn biết rằng nó không tin tưởng vào chứng chỉ.


11

Nếu bạn sử dụng lõi .net, hãy thử điều này:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
        new X509ServiceCertificateAuthentication()
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
        };

1
Cảm ơn, nó hoạt động. Nhưng nó không có gì để làm với lõi .net. Đó là một công thức phổ quát :)
Alexander

7

Vui lòng thực hiện các bước sau:

  1. Mở liên kết dịch vụ trong IE.

  2. Nhấp vào đề cập lỗi chứng chỉ trong thanh địa chỉ và nhấp vào Xem chứng chỉ.

  3. Kiểm tra phát hành cho: tên.

  4. Lấy tên đã ban hành và thay thế đề cập localhost trong dịch vụ và tên địa chỉ cơ sở điểm cuối của khách hàng bằng một tên miền đủ điều kiện (FQDN).

Ví dụ: https: // localhost : 203 / SampleService.svc Đến https: // INL-126166-.groupinfra.com : 203 / SampleService.svc


Tuyệt vời, cảm ơn vì câu trả lời này! Giải quyết các vấn đề mà không thực hiện bất kỳ thay đổi mã.
Vipin Dubey

6

Ngoài các câu trả lời ở trên, bạn có thể gặp phải lỗi này nếu máy khách của bạn đang chạy phiên bản TLS sai, ví dụ nếu máy chủ chỉ chạy TLS 1.2.

Bạn có thể sửa nó bằng cách sử dụng:

// tested in .NET 4.5:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

trong trường hợp của tôi, câu trả lời được chấp nhận đã không giúp tôi, nhưng câu trả lời này đã tạo ra một mánh khóe
Sergey

Đây là câu trả lời duy nhất sửa lỗi trong trường hợp của tôi.
Tolga

5

Tôi đã từng gặp vấn đề tương tự. Tôi cũng đã thêm chứng chỉ CA trong cửa hàng địa phương, nhưng tôi đã làm theo cách SAU.

Sử dụng Bảng điều khiển mmc (Bắt đầu -> Chạy -> mmc ), bạn nên thêm Chứng chỉ kèm làm tài khoản Dịch vụ (chọn tài khoản dịch vụ của IIS) hoặc Tài khoản máy tính (nó bổ sung cho mọi tài khoản trên máy)

Đây là hình ảnh của những gì tôi đang nói về Thêm snap-in cho tài khoản dịch vụ hoặc tài khoản máy tính

Từ đây, bạn có thể thêm chứng chỉ CA ( CA gốc đáng tin cậyCA trung gian ) và mọi thứ sẽ hoạt động tốt


4

Tôi đã có vấn đề tương tự với giấy chứng nhận tự ký. Tôi có thể giải quyết nó bằng cách sử dụng tên chứng chỉ giống như FQDN của máy chủ.

Lý tưởng nhất, phần SSL nên được quản lý ở phía máy chủ. Khách hàng không bắt buộc phải cài đặt bất kỳ chứng chỉ nào cho SSL. Ngoài ra, một số bài viết được đề cập về việc bỏ qua SSL từ mã máy khách. Nhưng tôi hoàn toàn không đồng ý với điều đó.


3

Tôi chỉ cần kéo chứng chỉ vào thư mục "Cơ quan chứng nhận gốc đáng tin cậy" và mọi thứ đều hoạt động tốt.

Oh. Và lần đầu tiên tôi đã thêm những điều sau đây từ Dấu nhắc của Quản trị viên:

netsh http add urlacl url=https://+:8732/Servicename user=NT-MYNDIGHET\INTERAKTIV

Tôi không chắc chắn về tên bạn cần cho người dùng (tên của tôi là tiếng Na Uy như bạn có thể thấy!) : user=NT-AUTHORITY/INTERACTIVE?

Bạn có thể thấy tất cả các urlacl hiện có bằng cách ban hành lệnh: netsh http show urlacl


0

Điều này xảy ra khi cố gắng kết nối với Dịch vụ WCF thông qua. IP, ví dụ như https://111.11.111.1:port/MyService.svctrong khi sử dụng chứng chỉ gắn với tên, ví dụ mysite.com.

Chuyển sang https://mysite.com:port/MyService.svcgiải quyết nó.



0

Chỉ cần sửa một vấn đề tương tự.

Tôi nhận ra rằng tôi có một nhóm ứng dụng đang chạy trong một tài khoản chỉ có quyền đọc đối với chứng chỉ mà nó được sử dụng.

Ứng dụng .NET có thể truy xuất chính xác chứng chỉ nhưng ngoại lệ đó chỉ được ném khi GetRequestStream () được gọi.

Quyền chứng chỉ có thể được quản lý thông qua bảng điều khiển MMC


0

Nếu bạn đang sử dụng lõi .net, thì trong quá trình phát triển, bạn có thể bỏ qua xác thực chứng chỉ bằng cách sử dụng các chỉ thị của trình biên dịch. Cách này sẽ chỉ xác nhận chứng chỉ để phát hành chứ không phải để gỡ lỗi:

#if (DEBUG)
        client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
                };   #endif

-6

Thêm mã này vào mã máy khách của bạn:

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(
    delegate
    {
        return true;
    });

4
Câu trả lời này không tốt lắm, vì nó không giải thích các rủi ro liên quan đến mã.
daveD
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.