Selamlar ile IIS bir WCF dinlenme hizmetine bağlanmak IIS'de, kendinden imzalı istemci sertifikası kimlik doğrulaması ile ', ancak uygulamayı çalıştırdığımda' yasak erişimi 'almaya devam ediyorum. WCF hizmetine yönelik bir istemci WCF'si iyi çalışıyor ve WCF hizmetine yönelik Android istemci uygulaması, 'istemci sertifikaları gerektirme' özelliğini devre dışı bıraktığımda da çalışıyor.Android Ben sadece JSON WCF dinlenme hizmetine bir işlemin ardından 'Bağlan gerçekleştirecek bir Android testi uygulaması oluşturmak çalışıyorum</p> <p>, kendinden imzalı istemci sertifikası kimlik doğrulaması
Tuhaf bölüm, Eclipse'nin istemci sertifikasının bulunduğunu ve bir KeyManager'ın onunla oluşturulduğunu bildirmesidir, ancak sunucuya hiçbir şey gönderilmez.
şu adımları
çocuk sertifikalarının bir serverCA.cer ve clientCA.cer olarak- yana sürdürülmektedir clientCA.cer iki anahtar depolamayı BKS biçiminde oluşturulan Portecle ile
- , clientCA PKI keystore.bks ve giriş
- PKI olarak rootca sahip olduğu diğer truststore.bks adlı içeren bir takma istemcisi olduğu dou için kullanılır PKI
- truststore.bks alınabilir eğer ks onay
- Her iki anahtar depolamayı res ilave edildi rootCA.cer/için Android
Tutulması ham içerir Android'de kendinden imzalı sertifikaların işlenmesi Birkaç örnek kullanmaya çalıştım ancak EasySSLSocketFactory ve EasySSLTrustManager'dan StackOverflow:self-signed-ssl-acceptance-android worked for the most part. Ben de varsayılan keytool ile keystores oluşturmayı denedim, ancak bu daha yanlış keystores oluşturulmasına neden olur.
Güncelleme 2011-03-17: IIS barındıran sistem bilgileri
sistem işletim sistemi IIS-5 .NET 4.0 ile Windows XP işletim sistemidir. IIS'deki hizmet, serverCA.cer sunucu sertifikası olarak atanmış ve istemci sertifikası gerektirir.
Üzerinde çalıştığım android sürümü Eclipse ile 2.3.3 ve Internet için izin ayarladı ve Eclipse projesinde bir ham kaynak olarak anahtar deposu ve güven deposunu eklediler.
Ayrıca, hata ayıklama modunda ararken, KeyManagerFactory.getKeyManagers() geri döndüğümde listede bir öğe olduğunu görüyorum. öncelikle bir WCF hizmeti ve müşteri arasında çalışmak zorunda olduğu
sertifikaları MakeCert ile oluşturulan:
Burada konuyla kullanmak eylemlerin/kod detaylar.yapılandırılmış
makecert.exe -r -n "CN=rootCA,O=Organization,OU=Org Unit,L=Location,S=SH,C=Country" -pe -ss root -sr LocalMachine -sky exchange -m 96 -a sha1 -len 2048 rootCA.cer -sv rootCA.pvk
makecert.exe -n "CN=serverCA" -pe -ss my -sr LocalMachine -sky exchange -m 96 -in "rootCA" -is root -ir LocalMachine -a sha1 -eku 1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2 serverCA.cer
makecert.exe -n "CN=clientCA" -pe -ss my -sr CurrentUser -sky exchange -m 96 -in "rootCA" -is root -ir LocalMachine -a sha1 -eku 1.3.6.1.5.5.7.3.2 clientCA.cer -sv clientCA.
pvk2pfx.exe -pvk clientCA.pvk -spc clientCA.cer -pfx clientCA.pfx
WCF izledi gibidir:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="consoleOutputBehavior" type="JsonTestService.ConsoleOutputBehaviorExtensionElement, JsonTestService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="JsonStandardEndpoint" defaultOutgoingResponseFormat="Json"
automaticFormatSelectionEnabled="true">
<security mode="Transport">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
</security>
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
<bindings>
<webHttpBinding>
<binding name="JsonBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
</security>
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp defaultBodyStyle="Wrapped" defaultOutgoingResponseFormat="Json" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="Custom" mapClientCertificateToWindowsAccount="false"
customCertificateValidatorType="JsonTestService.CustomX509CertificateValidator, JsonTestService"
/>
</clientCertificate>
<serviceCertificate findValue="serverCA" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="defaultBehavior" name="JsonTestService.TestService">
<endpoint address="json" behaviorConfiguration="jsonBehavior"
binding="webHttpBinding" bindingConfiguration="JsonBinding"
name="JsonEndpoint" contract="JsonTestService.ITestService" kind="webHttpEndpoint"
endpointConfiguration="JsonStandardEndpoint">
</endpoint>
</service>
</services>
</system.serviceModel>
<system.web>
<authentication mode="None" />
</system.web>
</configuration>
WCF hizmeti
namespace JsonTestService{
///
/// DataContract
///
[DataContract(Name = "Foo", Namespace = "http://www.example.com/data")]
public class FooDataContract
{
[DataMember(Order = 0)]
public string Item { get; set; }
[DataMember(Order = 1)]
public int Count { get; set; }
}
///
/// Service Contract
///
[ServiceContract(Namespace = "http://www.example.com/service")]
public interface ITestService
{
[OperationContract]
[WebInvoke(Method = "POST"
, ResponseFormat = WebMessageFormat.Json
, RequestFormat = WebMessageFormat.Json
, BodyStyle = WebMessageBodyStyle.WrappedRequest
, UriTemplate = "GetFoo.json/{name}?item={item}&count={countOfFoo}")]
FooDataContract[] GetFoo(string name, int item, int countOfFoo);
[OperationContract]
[WebInvoke(Method = "GET"
, ResponseFormat = WebMessageFormat.Json
, RequestFormat = WebMessageFormat.Json
, BodyStyle = WebMessageBodyStyle.WrappedRequest
, UriTemplate = "GetFooRaw.json")]
FooDataContract[] GetFooRaw();
}
///
/// Service Implementation
///
///
/// Each request will have its own instance of the service
///
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class TestService : ITestService
{
public FooDataContract[] GetFoo(string name, int item, int countOfFoo)
{
List result = null;
for (int i = 0; i();
result.Add(new FooDataContract()
{
// default to "null"
Name = (name ?? "null") + "_" + i,
Age = age
});
}
return result == null ? null : result.ToArray();
}
public FooDataContract[] GetFooRaw()
{
List result = new List();
for (int i = 0; i < 5; i++)
result.Add(new FooDataContract() { Item = (i + 1) * 6, Name = "Test" + i.ToString() });
return result.ToArray();
}
}
WCF çağrıları Android yöntem Nesne hizmet follo olarak Aşağıdaki bölüm
private KeyStore getKeyStore() throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException, UnrecoverableKeyException, Exception
{
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream in = this.getApplicationContext().getResources().openRawResource(R.raw.keystore);
try {
keystore.load(in, "changeit".toCharArray());
Key key = keystore.getKey("client", null); //It has no password and this way it finds the Key
}
catch (Exception e) {
throw e;
} finally {
in.close();
}
return keystore;
}
private KeyStore getTrustStore() throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException
{
KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream in = this.getApplicationContext().getResources().openRawResource(R.raw.truststore);
try {
truststore.load(in, "changeit".toCharArray());
} finally {
in.close();
}
return truststore;
}
EasySSLSocketFactory böylece biraz modifiye edilmiş istemci sertifika deposunu ve truststore almak için bir yöntem testSSLDataTransfer tarafından
private void testSSLDataTransfer() throws ClientProtocolException, IOException, Exception
{
try {
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(getKeyStore(),"",getTrustStore()), 443)); //password is empty
HttpParams params = new BasicHttpParams();
params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 1);
params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(1));
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "utf8");
ClientConnectionManager clientConnectionManager = new ThreadSafeClientConnManager(params, schemeRegistry);
HttpContext context = new BasicHttpContext();
DefaultHttpClient client = new DefaultHttpClient(clientConnectionManager, params);
HttpPost post = new HttpPost("https://10.12.14.16:443/JsonTest/TestService.svc/json/GetFoo.json/Test?item=12&count=2");
HttpGet get = new HttpGet("https://10.12.14.16:443/JsonTest/TestService.svc/json/GetFooBar.json");
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
post.setHeader("User-Agent", "android");
get.setHeader("Accept", "application/json");
get.setHeader("Content-type", "application/json");
get.setHeader("User-Agent", "android");
HttpResponse response = client.execute(get, context);
String statusLine = response.getStatusLine().toString(); //for debuf to see the response
HttpEntity responseEntity = response.getEntity();
InputStream stream = responseEntity.getContent();
InputStreamReader reader = new InputStreamReader(stream);
java.lang.StringBuffer stringBuffer = new java.lang.StringBuffer();
int read = 0;
while((read = reader.read()) >= 0)
stringBuffer.append((char)read);
String s = stringBuffer.toString();
stream.close();
} catch (ClientProtocolException e) {
throw e;
} catch (IOException e) {
String text = e.getMessage();
throw e;
} catch (Exception e) {
throw e;
}
}
kullanılır Çar kod şöyle görünüyor:
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyStore;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.scheme.LayeredSocketFactory;
import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* This socket factory will create ssl socket that accepts self signed
* certificate
*
* @author olamy
* @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse
* $
* @since 1.2.3
*/
public class EasySSLSocketFactory implements SocketFactory, LayeredSocketFactory {
private SSLContext sslcontext = null;
private KeyStore keystore = null;
private KeyStore truststore = null;
String keystorepassword = null;
public EasySSLSocketFactory()
{
}
public EasySSLSocketFactory(KeyStore keystore, String keystorepassword,KeyStore truststore)
{
this.keystore = keystore;
this.keystorepassword = keystorepassword;
this.truststore = truststore;
}
private static SSLContext createEasySSLContext(KeyStore keystore, String keystorepassword,KeyStore truststore) throws IOException {
try {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore, keystorepassword.toCharArray());
KeyManager[] list = keyManagerFactory.getKeyManagers();
SSLContext context = SSLContext.getInstance("TLS");
context.init(list, new TrustManager[] { new EasyX509TrustManager(truststore) }, null);
return context;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
private SSLContext getSSLContext() throws IOException {
if (this.sslcontext == null) {
this.sslcontext = createEasySSLContext(keystore, keystorepassword, truststore);
}
return this.sslcontext;
}
/**
* @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
* java.lang.String, int, java.net.InetAddress, int,
* org.apache.http.params.HttpParams)
*/
public Socket connectSocket(Socket sock, String host, int port,
InetAddress localAddress, int localPort, HttpParams params)
throws IOException, UnknownHostException, ConnectTimeoutException {
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(params);
InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
if ((localAddress != null) || (localPort > 0)) {
// we need to bind explicitly
if (localPort < 0) {
localPort = 0; // indicates "any"
}
InetSocketAddress isa = new InetSocketAddress(localAddress,
localPort);
sslsock.bind(isa);
}
sslsock.connect(remoteAddress, connTimeout);
sslsock.setSoTimeout(soTimeout);
return sslsock;
}
/**
* @see org.apache.http.conn.scheme.SocketFactory#createSocket()
*/
public Socket createSocket() throws IOException {
return getSSLContext().getSocketFactory().createSocket();
}
/**
* @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
*/
public boolean isSecure(Socket socket) throws IllegalArgumentException {
return true;
}
/**
* @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket,
* java.lang.String, int, boolean)
*/
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port,autoClose);
}
// -------------------------------------------------------------------
// javadoc in org.apache.http.conn.scheme.SocketFactory says :
// Both Object.equals() and Object.hashCode() must be overridden
// for the correct operation of some connection managers
// -------------------------------------------------------------------
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(EasySSLSocketFactory.class));
}
public int hashCode() {
return EasySSLSocketFactory.class.hashCode();
}
}
Bu hala geçerli mi? – LamonteCristo
@ makerofthings7 Hayır, bu artık geçerli değil (Aslında, her zaman olduğundan emin değilim) Önemsiz olmasa da, bir WCF servisine istemci sertifikası kimlik doğrulaması mümkündür. Bu soruya bakın: http://stackoverflow.com/questions/24476591 – Felix