2010-02-10 21 views
19

Şu anda, istemci web tarayıcısını kullanarak web sitesine eriştiği sürece, Karşılıklı Kimlik Doğrulama güvenliğini başarılı bir şekilde uyguladım. Çünkü tarayıcılar sizin için tüm sertifika alışverişlerini hallediyor. Şimdi, kullanıcıların sunucu tarafından gereken karşılıklı kimlik doğrulamayı kullanarak HTTPS üzerinden web hizmetlerine erişebilecekleri güvenli bir arayüz oluşturmam gerekiyor.Web hizmetleriyle karşılıklı kimlik doğrulaması

Öncelikle, bu konuda bana yardımcı olabilecek herkesin bildiği kaynaklar var mı? Oldukça uzun bir zaman aradım ve hiçbir şey bulamadım. Kimsenin bu konuda nasıl karar verebileceği hakkında başka ipuçları var mı?

İkinci olarak, bence en büyük engelim, sertifikaların nasıl işleneceğinin anlaşılmamasıdır. Sunucunun anahtarını kabul etme ve kendi anahtarımı sunucuya sunma konusunda nasıl pazarlık yaparım? Bu Java'da.

cevap

1

this blog entry'da basit bir formül verilmiştir.

Ancak, gerçek yanıtın, istemci tarafı HTTP etkileşimlerinizi uygulamak için kullandığınız Java API'larına bağlı olabileceğini düşünüyorum. Örneğin, JAX-RPC'yi kullanarak a bit differently öğelerini yapacağınız anlaşılıyor.

6

Web hizmeti kitaplığı, HTTP istemcisi olarak standart java.net.URL sınıfını kullanıyorsa, bazı system properties'u ayarlayabilirsiniz ve iki yönlü kimlik doğrulaması yerleşik HTTPS desteğiyle işlenecektir.

necessary properties şunlardır:

  • javax.net.ssl.trustStore: İçeriğinde kök CA sertifikaları
  • javax.net.ssl.keyStore: istemci sertifikası ve özel anahtar
  • javax.net.ssl.keyStorePassword İçeriyor: koruyucu şifresini müşterinin özel anahtar

Bunlar Ayarlar, tüm SSL bağlantıları için işlem tarafından varsayılanlar haline gelir. Daha iyi kontrol istiyorsanız, kendi SSLContext'unuzu kurmanız gerekir. Web servisinizin çalışma zamanı ile mümkün olup olmadığı, hangi çalışma zamanına bağlı olduğunuzu gösterir. Tarayıcı dışında SSL (aka iki yönlü SSL) ile karşılıklı kimlik doğrulaması için

11

, sen Aslında Diyelim ki ilk tek yönlü SSL için gerekenleri görelim ... gerekir:

  1. A sunucu deposu
  2. bir müşteri

sunucu deposu sunucunun (muhtemelen kendi imzasını) sertifika ve özel anahtar içerir truststore. Bu mağaza, sunucu tarafından iletileri imzalamak ve istemciye kimlik bilgilerini döndürmek için kullanılır.

İstemcinin güvenilen deposu, sunucunun (kendinden imzalı) sertifikasını (sunucu anahtar deposundan sunucu özel anahtarı olmadan tek başına bir sertifikaya ayıklanır) içerir. Sertifika, JRE ile birlikte verilen güven deposunda zaten bir sertifikaya sahip olduğunuz güvenilir bir CA tarafından imzalanmamışsa bu gereklidir. Bu adım bir güven zinciri oluşturmayı sağlar.

Bununla, tek yönlü SSL (geleneksel kullanım durumu) uygulayabilirsiniz.

  1. Bir müşteri deposu
  2. Bir sunucu truststore

: Eklemek gerekir böylece

iki yönlü SSL uygulamak için, bu kurulumu "simetrik" yapmak gerekir İstemci anahtar deposu müşterinin (muhtemelen kendinden imzalı) sertifikasını ve özel anahtarını içerir. Bu depo, istemci tarafından, sunucu anahtar deposundan aynı amaçla, yani TLS karşılıklı kimlik doğrulama el sıkışma sırasında sunucuya istemci kimlik bilgilerini göndermek için kullanılır.

Sunucu güven deposu istemcilerinin (kendinden imzalı) bağımsız sertifikalarını (istemcilerde gizli anahtar olarak istemcideki anahtar deposundan bağımsız sertifikalara ayıklanır) içerir. Bu daha önce belirtilen aynı nedenlerle gereklidir.

Bazı kaynaklar bu kadar şeye oluşturmak için yardımcı olmak ve son çözümleri uygulamak için:

+3

oldukça iyi karşılıklı kimlik doğrulama kavramını açıkladım rağmen, bağlantılar hiç çok yararlı değildir. Java web servis güvenliği 2006'dan beri adil bir şekilde değişti! :) – Catchwa

14

Uzun geçirdi Bunun üzerine zaman ama sonunda bir örnek buldum müttefik çalışır. Glassfish ve Netbeans tabanlı ama sanırım başka ortamlarda (örneğin, Eclipse ve Tomcat) çalışmış olabilirsiniz. Kendi sertifikaları, GlassFish ile önceden yüklenmiş gelenler kullanmak istediğinizde

http://java.sun.com/webservices/reference/tutorials/wsit/doc/WSIT_Security9.html#wp162511

olsa buldum sorun

olduğunu.

Not: Ben bir güvenlik uzmanı değilim. Bunu bir üretim ortamına yaymayın!

Ben NetBeans 6.9 kullanıyorum Bunu yapmak için JDK 1.6 GlassFish 3.0.1 ve OpenSSL v1.0 (Ben gayri resmi Win32 ikilileri kullanıyorum) GlassFish yönetici konsolunda

# Create the CA 
mkdir ca server client 
cd ca 
openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.pem 
echo 02 > serial.txt 
cd .. 

# Creating the Server Keystore 

openssl req -days 3650 -newkey rsa:1024 -keyout server/server.key -out server/server.req 
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in server/server.req -out server/server.crt 
openssl pkcs12 -export -inkey server/server.key -in server/server.crt -out server/server.p12 -name server 
keytool -importkeystore -destkeystore server/server.jks -deststoretype jks -srckeystore server/server.p12 -srcstoretype pkcs12 
keytool -exportcert -alias server -keystore server/server.jks -file server/server.cer 

# Create the Client Keystore 

openssl req -days 3650 -newkey rsa:1024 -keyout client/client1.key -out client/client1.req 
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in client/client1.req -out client/client1.crt 
openssl pkcs12 -export -inkey client/client1.key -in client/client1.crt -out client/client1.p12 -name client1 
keytool -importkeystore -destkeystore client/client1.jks -deststoretype jks -srckeystore client/client1.p12 -srcstoretype pkcs12 
keytool -exportcert -alias client1 -keystore client/client1.jks -file client/client1.cer 

# Import public keys and certificates into each others keystores 

keytool -import -noprompt -trustcacerts -alias client1 -file client/client1.cer -keystore server/server.jks 
keytool -import -noprompt -trustcacerts -alias server -file server/server.cer -keystore client/client1.jks 
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore server/server.jks 
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore client/client1.jks 
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\cacerts.jks" 
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\Java\jdk1.6\jre\lib\security\cacerts" 
move "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks" "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks.backup" 
copy server\server.jks "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks" 

, http-dinleyicinizdeki Güvenliği etkinleştirin, SSL3, TLS ve İstemci Kimlik Doğrulama kutularını işaretleyin, Sertifika NickName'i sunucuya ayarlayın, yapılandırmak için Anahtar Deposu \ keystore.jks, Trust Store yapılandırmak için \ Keystore.jks, Trust Algorithm'i PKIX'e yapılandırın ve Max Sertifika Uzunluğunu 5 olarak bırakın.

NetBeans'da yeni bir Web Uygulaması projesi oluşturun. Bunun içinde yeni bir Web hizmeti oluşturun.

My Web Servis kodu şuna benziyordu:

@WebService() 
public class ListProducts { 

    @Resource WebServiceContext context; 

    @WebMethod(operationName = "listProducts") 
    public String listProducts() { 
    return context.getUserPrincipal().toString(); 
    } 

} 

Sağ Web Hizmeti tıklayıp Düzenleme Web Servis Özellikleri seçin. Güvenli Hizmet kutusunu işaretleyin ve Güvenlik Mekanizması olarak Karşılıklı Sertifika Güvenliği'ni seçin. Yapılandır ... düğmesine tıklayın ve İmzayı Şifrele kutusunu işaretleyin. Şimdi Geliştirme Varsayılanlarını Kullan kutusunu işaretleyin ve ardından Keystore düğmesine tıklayın. Server.jks anahtar deponuzun konumunu belirleyin ve server diğer adlarını seçin.Truststore yapılandırması için de aynısını yapın (burada bir takma ad seçmek zorunda olmasa da).

Istemci1.p12 istemci sertifikasını tarayıcınıza aktarın. Web Hizmetinizi Glassfish'e dağıtın. Web hizmetinizi bir tarayıcıda açın ve HTTPS ile dağıtılan WSDL'ye göz atın. WSDL ve diğer şemaları indirin. Başvurulan şemaları yerel kopyalara yeniden adlandırın, böylece WSDL2Java NetBeans kullandığınızda herhangi bir uzak kaynak kullanmazsınız. (Bu paragraf, WSDL'nizi onaylanmış bir sertifikaya sahip istemcilere sınırladığınız, ancak NetBeans'in söz konusu sertifikaya erişimi olmadığı için uzaktan getiremediğinden kaynaklanır).

Yeni bir Java Projesi oluşturun. Yeni bir Web Hizmeti İstemcisi oluşturun. İstendiğinde, NetBeans'i kaydedilmiş WSDL dosyanıza yönlendirin. METRO2.0 kitaplık dosyalarını içe aktarın (C:\Program Files\Netbeans 6.9\enterprise\modules\ext\metr\webservices-*.jar). Benim kod aşağıdaki gibi görünüyordu:

public static void main(String[] args) { 
    System.getProperties().put("javax.net.ssl.keyStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks"); 
    System.getProperties().put("javax.net.ssl.keyStorePassword", "changeit"); 
    System.getProperties().put("javax.net.ssl.trustStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks"); 
    System.getProperties().put("javax.net.ssl.trustStorePassword", "changeit"); 
    System.out.println(new ListProductsService().getListProductsPort().listProducts()); 
} 

Kopya webservices-api.jar sizin Java \ JDK 1.6 \ jre \ lib \ onayladı dizin içine. Web Hizmeti referansını sağ tıklayın ve Web Hizmeti Niteliklerini Düzenle seçeneğini seçin. Anahtar deposu konumunu client1.jks olarak ayarlayın ve diğer adı client1 olarak ayarlayın. Truststore konumunu client1.jks olarak ayarlayın ve diğer adı server olarak ayarlayın.

Umarım artık müşteri çalıştırabilir ve böylece gibi çıktı görmelisiniz: [email protected], CN=Bob Smith, OU=Something, O=SomethingElse, L=AnyTown, ST=AnyState, C=US