Bagaimana mengatasi "Tidak dapat membangun hubungan kepercayaan untuk saluran aman SSL / TLS dengan otoritas"

139

Benar-benar berpikir saya telah memperbaiki masalah ini, tetapi itu hanya disamarkan sebelumnya.

Saya memiliki layanan WCF yang dihosting di IIS 7 menggunakan HTTPS. Saat saya menjelajah ke situs ini di Internet Explorer, ia bekerja seperti pesona, ini karena saya telah menambahkan sertifikat ke penyimpanan otoritas sertifikat akar lokal.

Saya mengembangkan di 1 mesin, jadi klien dan server adalah mesin yang sama. Sertifikat ditandatangani sendiri langsung dari snap in manajemen IIS 7.

Saya terus mendapatkan kesalahan ini sekarang ...

Tidak dapat membangun hubungan kepercayaan untuk saluran aman SSL / TLS dengan otoritas.

... saat dipanggil dari konsol klien.

Saya secara manual memberi diri saya izin dan layanan jaringan ke sertifikat, menggunakan findprivatekeydan menggunakan cacls.exe.

Saya mencoba menyambung ke layanan menggunakan SOAPUI, dan berhasil, jadi pasti ada masalah dalam aplikasi klien saya, yang merupakan kode berdasarkan apa yang digunakan untuk bekerja dengan http.

Di mana lagi saya bisa mencari, saya sepertinya sudah kehabisan semua kemungkinan mengapa saya tidak bisa terhubung?

JL.
sumber
Jika Anda memiliki kendali atas pembuatan sertifikat, jangan lupa tentang "Nama Subjek Alternatif". Seperti Anda bisa meletakkan wild card di "* .full.domainname.com". Lihat digicert.com/subject-alternative-name.htm
granadaCoder

Jawaban:

199

Sebagai solusinya, Anda dapat menambahkan penangan ke ServicePointManager's ServerCertificateValidationCallbackdi sisi klien:

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

tetapi ketahuilah bahwa ini bukan praktik yang baik karena ini sepenuhnya mengabaikan sertifikat server dan memberi tahu manajer titik layanan bahwa sertifikat apa pun yang baik-baik saja yang dapat membahayakan keamanan klien secara serius. Anda dapat memperbaiki ini dan melakukan beberapa pemeriksaan khusus (untuk nama sertifikat, hash dll). setidaknya Anda dapat menghindari masalah selama pengembangan saat menggunakan sertifikat pengujian.

Joachim Kerschbaumer
sumber
9
Saya pikir sebagian besar pengaturan publik akan menggunakan sertifikat yang dibeli tetapi selama dev menggunakan kode di atas dalam pernyataan #if bersyarat. Devs perusahaan harus umumnya setup CA internal server >> technet.microsoft.com/en-us/library/cc875810.aspx
Lukas Puplett
2
Membantu saya mencari cara agar panggilan SSL WCF saya berfungsi dengan Fiddler2 untuk debugging.
Roger Willcocks
2
@karank Pertimbangkan untuk meletakkannya di metode Application_Start di Global.asax (lihat stackoverflow.com/a/12507094/1175419 ). Saya sangat menyarankan menggunakan arahan kompilator # jika DEBUG atau sesuatu yang serupa seperti yang disebutkan dalam komentar Luke.
Rich C
4
Hebat! Anda dapat menggunakan ekspresi lambda sebagai System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => true;
Dhanuka777
Sedikit penjelasan tambahan dapat ditemukan di sini: blog.effectivemessaging.com/2015_09_01_archive.html
granadaCoder
41

Ketika saya memiliki masalah ini, itu karena client.config memiliki titik akhir seperti:

 https://myserver/myservice.svc 

tapi sertifikatnya sudah menunggu

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

Mengubah titik akhir agar sesuai dengan FQDN server menyelesaikan masalah saya. Saya tahu ini bukan satu-satunya penyebab masalah ini.

Mike Cheel
sumber
Saya baru saja mengalami masalah ini lagi dan kali ini harus dengan sertifikat yang salah digunakan. Sepertinya dalam kedua kasus itu ada hubungannya dengan mencocokkan nama dengan benar.
Mike Cheel
3
Konfigurasi yang dibuat secara otomatis telah <endpoint address = " localhost / myservice.svc " mengubahnya menjadi <endpoint address = " mymachine.mydoman.com/myservice.svc " menyelesaikan ini.
knightscharge
Ini benar-benar masalah saya dan saya butuh dua hari untuk menemukan jawaban Anda. +1, saya akan memberi Anda +1000 jika saya bisa.
AussieJoe
20

Masalah Anda muncul karena Anda menggunakan kunci yang ditandatangani sendiri. Klien tidak mempercayai kunci ini, dan kunci itu sendiri tidak menyediakan rantai untuk divalidasi atau daftar pencabutan sertifikat.

Anda memiliki beberapa opsi - Anda bisa

  1. matikan validasi sertifikat pada klien (langkah buruk, serangan man in the middle berlimpah)

  2. gunakan makecert untuk membuat root CA dan membuat sertifikat dari itu (ok pindah, tapi masih belum ada CRL)

  3. buat root CA internal menggunakan Windows Certificate Server atau solusi PKI lainnya lalu percayakan sertifikat root tersebut (agak sulit untuk dikelola)

  4. membeli sertifikat SSL dari salah satu CA terpercaya (mahal)

blowdart
sumber
3
Mengenai (4), StartSSL benar-benar akan memberi Anda sertifikat Kelas 1 gratis yang berfungsi di semua browser utama. Mereka bekerja dengan baik untuk saya untuk setengah lusin situs bandwidth rendah saya.
moodboom
Saya pikir # 2 di daftar ini ... url ini mungkin membantu: blogs.technet.microsoft.com/jhoward/2005/02/02/… "Cara menggunakan MakeCert untuk otoritas sertifikasi root tepercaya dan penerbitan sertifikat SSL"
granadaCoder
1
Catatan: StartCom tidak lagi dapat dipercaya - dan baru saja dihapus dari Chrome en.wikipedia.org/wiki/StartCom
Simon_Weaver
20

dua yang pertama menggunakan lambda, yang ketiga menggunakan kode biasa ... semoga bermanfaat

            //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;
    }
Sebastian Castaldi
sumber
1
// Percayai semua sertifikat System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => {return true; }; // percayai pengirim System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => {return cert.Subject.Contains ("ca-l-9wfvrm1.ceridian.ca"); };
VoodooChild
1
Setiap cracker dapat memalsukan sertifikat dengan lulus semua tes di atas. Ini tidak aman.
Bjartur Thorlacius
16

Solusi satu baris. Tambahkan ini di mana saja sebelum memanggil server di sisi klien:

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

Ini sebaiknya hanya digunakan untuk tujuan pengujian karena klien akan melewati pemeriksaan keamanan SSL / TLS.

Gaspa79
sumber
2
Solusi brilian untuk pengujian. Kami menggunakan layanan yang penyedia telah membuat keamanan menjadi neraka hidup dengan rantai sertifikat keamanan yang berbelit-belit dan sampai kami bisa mendapatkan sertifikat miring dan rantai mereka untuk bekerja dengan benar, solusi ini adalah satu-satunya hal yang memungkinkan kami untuk melanjutkan pengembangan.
markaaronky
13

Saya mengalami masalah yang sama dan saya dapat mengatasinya dengan dua solusi: Pertama, saya menggunakan snap-in MMC "Sertifikat" untuk "Akun komputer" dan menyeret sertifikat yang ditandatangani sendiri ke folder "Otoritas Sertifikasi Root Terpercaya" . Ini berarti komputer lokal (yang menghasilkan sertifikat) sekarang akan mempercayai sertifikat itu. Kedua, saya perhatikan bahwa sertifikat dibuat untuk beberapa nama komputer internal, tetapi layanan web sedang diakses menggunakan nama lain. Ini menyebabkan ketidakcocokan saat memvalidasi sertifikat. Kami membuat sertifikat untuk computer.operations.local, tetapi mengakses layanan web menggunakan https://computer.internaldomain.companydomain.com . Saat kami mengalihkan URL ke yang digunakan untuk menghasilkan sertifikat, kami tidak lagi menemukan kesalahan.

Mungkin hanya mengganti URL akan berhasil, tetapi dengan membuat sertifikat dipercaya, Anda juga menghindari layar merah di Internet Explorer yang memberi tahu Anda bahwa ia tidak mempercayai sertifikat tersebut.

Jeroen-bart Engelen
sumber
Awalnya ini tidak berhasil untuk saya. Saya harus melakukan satu modifikasi pada langkah-langkah di atas: Saat menyeret sertifikat, pastikan untuk menahan tombol Ctrl agar sertifikat disalin , tidak dipindahkan dari Pribadi / Sertifikat ke Otoritas / Sertifikat Sertifikasi Root Terpercaya .
Metalogic
11

Jika Anda menggunakan .net core coba ini:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
        new X509ServiceCertificateAuthentication()
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
        };
Grzegorz J
sumber
1
Terima kasih, ini berhasil. Tapi itu tidak ada hubungannya dengan inti .net. Ini resep universal :)
Alexander
7

Harap lakukan langkah-langkah berikut:

  1. Buka tautan layanan di IE.

  2. Klik pada kesalahan sertifikat yang disebutkan di bilah alamat dan klik Lihat sertifikat.

  3. Cek dikeluarkan untuk: nama.

  4. Ambil nama yang dikeluarkan dan ganti penyebutan localhost dalam layanan dan nama alamat dasar titik akhir klien dengan nama domain yang memenuhi syarat penuh (FQDN).

Untuk Contoh: https: // localhost : 203 / SampleService.svc To https: // INL-126166-.groupinfra.com : 203 / SampleService.svc

Rahul Rai
sumber
Bagus, terima kasih atas jawaban ini! Memecahkan masalah tanpa membuat perubahan kode apa pun.
Vipin Dubey
6

Selain jawaban di atas, Anda mungkin mengalami kesalahan ini jika klien Anda menjalankan versi TLS yang salah, misalnya jika server hanya menjalankan TLS 1.2.

Anda dapat memperbaikinya dengan menggunakan:

// tested in .NET 4.5:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
NMrt
sumber
dalam kasus saya, jawaban yang diterima tidak membantu saya, tetapi yang ini berhasil
Sergey
Ini adalah satu-satunya jawaban yang memperbaiki kesalahan dalam kasus saya.
Tolga
Juga ini adalah trik yang membantu saya, meskipun dengan .Net 4.7.2
phifi
5

Saya memiliki masalah yang sama. Saya juga telah menambahkan sertifikat CA di toko lokal, tetapi saya melakukannya dengan cara yang SALAH.

Menggunakan Konsol mmc (Mulai -> Jalankan -> mmc ) Anda harus menambahkan Sertifikat snap-in sebagai akun Layanan (memilih akun layanan IIS) atau akun Komputer (ditambahkan untuk setiap akun di mesin)

Berikut gambar dari apa yang saya bicarakan Tambahkan snap-in untuk akun layanan atau akun komputer

Mulai sekarang, Anda dapat menambahkan sertifikat CA ( CA Root Tepercaya dan CA Menengah ), dan semuanya akan berfungsi dengan baik

dar0x
sumber
4

Saya memiliki masalah serupa dengan sertifikat yang ditandatangani sendiri. Saya bisa mengatasinya dengan menggunakan nama sertifikat yang sama dengan FQDN server.

Idealnya, bagian SSL harus dikelola di sisi server. Klien tidak perlu memasang sertifikat apa pun untuk SSL. Selain itu, beberapa postingan menyebutkan tentang mengabaikan SSL dari kode klien. Tapi saya sangat tidak setuju dengan itu.

Umesh Bhavsar
sumber
3

Saya baru saja menyeret sertifikat ke folder "Otoritas Sertifikasi Root Terpercaya" dan voila semuanya bekerja dengan baik.

Oh. Dan saya pertama kali menambahkan yang berikut ini dari Command Prompt Administrator:

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

Saya tidak yakin dengan nama yang Anda butuhkan untuk pengguna tersebut (nama saya adalah bahasa Norwegia seperti yang Anda lihat!) user=NT-AUTHORITY/INTERACTIVE:?

Anda dapat melihat semua urlacl yang ada dengan mengeluarkan perintah: netsh http show urlacl

Haguna
sumber
0

Ini terjadi saat mencoba menyambung ke Layanan WCF melalui. IP misalnya https://111.11.111.1:port/MyService.svcsaat menggunakan sertifikat yang terkait dengan nama misalnya mysite.com.

Beralih ke https://mysite.com:port/MyService.svcmenyelesaikannya.

lko
sumber
0

Baru saja memperbaiki masalah serupa.

Saya menyadari saya memiliki kumpulan aplikasi yang berjalan di bawah akun yang hanya memiliki izin membaca atas sertifikat yang digunakan.

Aplikasi .NET bisa dengan benar mengambil sertifikat tapi pengecualian itu dilemparkan hanya ketika GetRequestStream () dipanggil.

Izin sertifikat dapat dikelola melalui konsol MMC

Alberto
sumber
0

Jika Anda menggunakan inti .net, maka selama pengembangan Anda dapat melewati validasi sertifikat dengan menggunakan arahan compiler. Dengan cara ini hanya akan memvalidasi sertifikat untuk rilis dan bukan untuk debug:

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

Saya hanya ingin menambahkan sesuatu ke jawaban @NMrt yang sudah menunjukkan:

Anda dapat mengalami kesalahan ini jika klien Anda menjalankan versi TLS yang salah, misalnya jika server hanya menjalankan TLS 1.2.

Dengan Framework 4.7.2, jika Anda tidak secara eksplisit mengkonfigurasi kerangka target di web.config Anda seperti ini

<system.web>
  <compilation targetFramework="4.7" />
  <httpRuntime targetFramework="4.7" />
</system.web>

protokol keamanan default sistem Anda akan diabaikan dan sesuatu yang "lebih rendah" mungkin digunakan sebagai gantinya. Dalam kasus saya Ssl3 / Tls, bukan Tls13.

  • Anda juga dapat memperbaiki ini dalam kode dengan mengatur SecurityProtocol (membuat protokol lain tetap berfungsi):

    System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls11;
    System.Net.ServicePointManager.SecurityProtocol &= ~System.Net.SecurityProtocolType.Ssl3;
    
  • atau bahkan dengan menambahkan kunci registri untuk mengaktifkan atau menonaktifkan crypto yang kuat

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
    "SchUseStrongCrypto"=dword:00000001
    

Posting blog ini mengarahkan saya ke arah yang benar dan menjelaskan latar belakang lebih baik dari yang saya bisa:

https://www.ryadel.com/en/asp-net-client-server-cannot-comunicate-because-they-possess-common-algorithm-how-to-fix-c-sharp/

phifi
sumber
-6

Tambahkan ini ke kode klien Anda:

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(
    delegate
    {
        return true;
    });
pengguna662285
sumber
4
Jawaban ini tidak terlalu bagus, karena tidak menjelaskan risiko yang terkait dengan kode.
daveD