Saya memiliki klien layanan web Java, yang menggunakan layanan web melalui HTTPS.
import javax.xml.ws.Service;
@WebServiceClient(name = "ISomeService", targetNamespace = "http://tempuri.org/", wsdlLocation = "...")
public class ISomeService
extends Service
{
public ISomeService() {
super(__getWsdlLocation(), ISOMESERVICE_QNAME);
}
Ketika saya terhubung ke URL layanan ( https://AAA.BBB.CCC.DDD:9443/ISomeService
), saya mendapatkan pengecualian java.security.cert.CertificateException: No subject alternative names present
.
Untuk memperbaikinya, saya pertama kali menjalankan openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt
dan mendapatkan konten berikut dalam file certs.txt
:
CONNECTED(00000003)
---
Certificate chain
0 s:/CN=someSubdomain.someorganisation.com
i:/CN=someSubdomain.someorganisation.com
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=someSubdomain.someorganisation.com
issuer=/CN=someSubdomain.someorganisation.com
---
No client certificate CA names sent
---
SSL handshake has read 489 bytes and written 236 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 512 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : RC4-MD5
Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Session-ID-ctx:
Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Key-Arg : None
Start Time: 1382521838
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
AFAIK, sekarang saya perlu
- ekstrak bagian
certs.txt
antara-----BEGIN CERTIFICATE-----
dan-----END CERTIFICATE-----
, - memodifikasinya sehingga nama sertifikat sama dengan
AAA.BBB.CCC.DDD
dan - kemudian impor hasil menggunakan
keytool -importcert -file fileWithModifiedCertificate
(di manafileWithModifiedCertificate
adalah hasil operasi 1 dan 2).
Apakah ini benar?
Jika demikian, bagaimana tepatnya saya dapat membuat sertifikat dari langkah 1 bekerja dengan alamat alamat IP ( AAA.BBB.CCC.DDD
)?
Pembaruan 1 (23.10.2013 15:37 MSK): Sebagai jawaban atas pertanyaan serupa , saya membaca yang berikut ini:
Jika Anda tidak mengontrol server itu, gunakan nama host-nya (asalkan setidaknya ada CN yang cocok dengan nama host itu di sertifikat yang ada).
Apa sebenarnya arti "menggunakan"?
sumber
Saya memiliki masalah yang sama dan diselesaikan dengan kode ini. Saya meletakkan kode ini sebelum panggilan pertama ke layanan web saya.
Sederhana dan berfungsi dengan baik.
Ini sumber aslinya.
sumber
return hostname.equals("localhost");
, jika itu yang ingin Anda lakukan. Iniif
benar-benar berlebihan.HttpsURLConnection connection = (HttpsURLConnection) obj.openConnection();
. Juga, apakah ini mengabaikan setiap sertifikat? Karena saya melihat solusi seperti itu rentan terhadap keamanan. Terima kasih!Ini adalah pertanyaan lama, namun saya mengalami masalah yang sama saat berpindah dari JDK 1.8.0_144 ke jdk 1.8.0_191
Kami menemukan petunjuk di changelog:
Changelog
kami menambahkan properti sistem tambahan berikut, yang membantu dalam kasus kami untuk memecahkan masalah ini:
sumber
Verifikasi identitas sertifikat dilakukan terhadap apa yang diminta klien.
Saat klien Anda menggunakan
https://xxx.xxx.xxx.xxx/something
(xxx.xxx.xxx.xxx
dengan alamat IP), identitas sertifikat diperiksa terhadap alamat IP ini (secara teori, hanya menggunakan ekstensi IP SAN).Jika sertifikat Anda tidak memiliki IP SAN, tetapi DNS SAN (atau jika tidak ada DNS SAN, Nama Umum di Subjek DN), Anda bisa membuatnya berfungsi dengan membuat klien Anda menggunakan URL dengan nama host itu sebagai gantinya (atau nama host yang sertifikatnya akan valid, jika ada beberapa kemungkinan nilai). Misalnya, jika Anda memiliki nama untuk
www.example.com
, gunakanhttps://www.example.com/something
.Tentu saja, Anda memerlukan nama host itu untuk menyelesaikan ke alamat IP itu.
Selain itu, jika ada DNS SAN, CN di Subjek DN akan diabaikan, jadi gunakan nama yang cocok dengan salah satu SAN DNS dalam kasus ini.
sumber
http://www.example.com/someservice
. Apakah benar bahwa agar sertifikat berfungsi dengan alamat berbasis IP (https://AAA.BBB.CCC.DDD:9443/ISomeService
), saya perlu menyetel semuaCN
bidang keAAA.BBB.CCC.DDD
(gantisomeSubdomain.someorganisation.com
denganAAA.BBB.CCC.DDD
di file di atas) dan mengimpor file sertifikat yang dihasilkan?/etc/hosts
file Anda atau yang setaraUntuk mengimpor sertifikat:
openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt
Ini akan mengekstrak sertifikat dalam format PEM.openssl x509 -in certs.txt -out certs.der -outform DER
sudo keytool -importcert -file certs.der -keystore <path-to-cacerts>
Kata sandi cacerts default adalah 'changeit'.Jika sertifikat dikeluarkan untuk FQDN dan Anda mencoba menghubungkan dengan alamat IP di kode Java Anda, ini mungkin harus diperbaiki dalam kode Anda daripada mengotak-atik sertifikat itu sendiri. Ubah kode Anda untuk terhubung dengan FQDN. Jika FQDN tidak dapat diselesaikan pada mesin dev Anda, cukup tambahkan ke file host Anda, atau konfigurasikan mesin Anda dengan server DNS yang dapat menyelesaikan FQDN ini.
sumber
Saya memperbaiki masalah ini dengan cara yang benar dengan menambahkan nama alt subjek dalam sertifikat daripada membuat perubahan apa pun dalam kode atau menonaktifkan SSL tidak seperti jawaban lain yang disarankan di sini. Jika Anda melihat dengan jelas pengecualian mengatakan "Nama alt subjek hilang" jadi cara yang benar adalah menambahkannya
Silakan lihat tautan ini untuk memahami langkah demi langkah .
Kesalahan di atas berarti file JKS Anda tidak memiliki domain yang diperlukan tempat Anda mencoba mengakses aplikasi. Anda harus Menggunakan Open SSL dan alat kunci untuk menambahkan beberapa domain
echo '[ subject_alt_name ]' >> openssl.cnf
echo 'subjectAltName = DNS:example.mydomain1.com, DNS:example.mydomain2.com, DNS:example.mydomain3.com, DNS: localhost'>> openssl.cnf
openssl req -x509 -nodes -newkey rsa:2048 -config openssl.cnf -extensions subject_alt_name -keyout private.key -out self-signed.pem -subj '/C=gb/ST=edinburgh/L=edinburgh/O=mygroup/OU=servicing/CN=www.example.com/[email protected]' -days 365
Ekspor file kunci publik (.pem) ke format PKS12. Ini akan meminta Anda memasukkan kata sandi
Buat a.JKS dari PEM yang ditandatangani sendiri (Keystore)
Hasilkan Sertifikat dari Keystore atau file JKS di atas
Karena sertifikat di atas adalah Self Signed dan tidak divalidasi oleh CA, maka perlu ditambahkan di Truststore (file Cacerts di lokasi di bawah untuk MAC, untuk Windows, cari tahu di mana JDK Anda diinstal.)
Jawaban asli diposting di tautan ini di sini .
sumber
Anda mungkin tidak ingin menonaktifkan semua Verifikasi ssl sehingga Anda dapat menonaktifkan verifikasi hostName melalui ini yang sedikit kurang menakutkan daripada alternatif:
[EDIT]
Seperti yang disebutkan oleh conapart3
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
sekarang sudah tidak digunakan lagi, jadi mungkin akan dihapus di versi yang lebih baru, jadi Anda mungkin akan dipaksa di masa depan untuk menggulung milik Anda sendiri, meskipun saya masih akan mengatakan saya akan menghindari solusi apa pun di mana semua verifikasi dimatikan.sumber
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
sekarang tidak digunakan lagi.Masalah saya dengan mendapatkan kesalahan ini telah diatasi dengan menggunakan URL lengkap "qatest.ourCompany.com/webService" bukan hanya "qatest / webService". Alasannya adalah bahwa sertifikat keamanan kami memiliki karakter pengganti yaitu "* .PerusahaanAnda.com". Setelah saya memasukkan alamat lengkap pengecualiannya hilang. Semoga ini membantu.
sumber
Sudah menjawabnya di https://stackoverflow.com/a/53491151/1909708 .
Ini gagal karena nama umum sertifikat (
CN
dalam sertifikasiSubject
) maupun nama alternatif (Subject Alternative Name
dalam sertifikat) tidak cocok dengan nama host target atau alamat IP.Misalnya, dari JVM, saat mencoba menyambungkan ke alamat IP (
WW.XX.YY.ZZ
) dan bukan nama DNS ( https://stackoverflow.com ), sambungan HTTPS akan gagal karena sertifikat yang disimpan di java truststorecacerts
mengharapkan nama umum (atau nama alternatif sertifikat seperti stackexchange.com atau * .stackoverflow.com dll.) agar sesuai dengan alamat target.Silakan periksa: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#HostnameVerifier
Di atas, berikan
HostnameVerifier
objek yang diimplementasikan yang selalu mengembalikantrue
:sumber
Untuk Spring Boot
RestTemplate
:org.apache.httpcomponents.httpcore
ketergantungangunakan
NoopHostnameVerifier
untuk pabrik SSL:sumber
Saya mendapat pertanyaan ini setelah mendapat pesan kesalahan yang sama. Namun dalam kasus saya, kami memiliki dua URL dengan subdomain berbeda ( http://example1.xxx.com/someservice dan http://example2.yyy.com/someservice ) yang diarahkan ke server yang sama. Server ini hanya memiliki satu sertifikat karakter pengganti untuk domain * .xxx.com. Saat menggunakan layanan melalui domain kedua, sertifikat yang ditemukan (* .xxx.com) tidak cocok dengan domain yang diminta (* .yyy.com) dan kesalahan terjadi.
Dalam hal ini kita tidak boleh mencoba untuk memperbaiki kesalahan pesan dengan menurunkan keamanan SSL, tetapi harus memeriksa server dan sertifikat di atasnya.
sumber
sumber
Saya telah melalui 2 cara SSL di springboot. Saya telah membuat semua layanan konfigurasi yang benar tomcat server dan pemanggil layanan RestTemplate. tapi saya mendapatkan kesalahan sebagai "java.security.cert.CertificateException: Tidak ada nama alternatif subjek"
Setelah melalui solusi, saya menemukan, JVM membutuhkan sertifikat ini jika tidak maka akan memberikan kesalahan jabat tangan.
Sekarang, bagaimana menambahkan ini ke JVM.
buka file jre / lib / security / cacerts. kita perlu menambahkan file sertifikat server kita ke file cacerts jvm ini.
Perintah untuk menambahkan sertifikat server ke file cacerts melalui baris perintah di windows.
C: \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ security> keytool -import -noprompt -trustcacerts -alias sslserver -file E: \ spring_cloud_sachin \ ssl_keys \ sslserver.cer -keystore cacerts -storepass changeit
Periksa sertifikat server diinstal atau tidak:
C: \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ security> keytool -list -keystore cacerts
Anda dapat melihat daftar sertifikat yang dipasang:
untuk detail lebih lanjut: https://sachin4java.blogspot.com/2019/08/javasecuritycertcertificateexception-no.html
sumber
tambahkan entri host dengan ip yang sesuai dengan CN di sertifikat
CN = someSubdomain.someorganisation.com
sekarang perbarui ip dengan nama CN tempat Anda mencoba mengakses url.
Itu berhasil untuk saya.
sumber
sumber
Jika Anda memiliki sertifikat dengan CN dan Nama Alternatif Subjek (SAN), jika Anda membuat permintaan berdasarkan konten CN, konten tertentu tersebut juga harus ada di SAN, jika tidak maka akan gagal dengan kesalahan yang dimaksud.
Dalam kasus saya CN memiliki sesuatu, SAN memiliki sesuatu yang lain. Saya harus menggunakan URL SAN, dan kemudian berfungsi dengan baik.
sumber
Tambahkan alamat IP Anda di file hosts. Yang ada di folder C: \ Windows \ System32 \ drivers \ etc. Tambahkan juga IP dan Nama Domain dari alamat IP. contoh: aaa.bbb.ccc.ddd [email protected]
sumber
Saya telah menyelesaikan masalah dengan cara berikut.
1. Membuat kelas. Kelas memiliki beberapa implementasi kosong
2. Membuat metode
sumber