2015-07-07 6 views
3

Я пытаюсь запустить HTTPS-сервер на устройстве Android с помощью NanoHttpd (моя конечная цель - запустить WSS-сервер на Android). Я успешно запускал HTTP-сервер и веб-узел с помощью NanoHttpd на Android. Я создал ключ на MAC, используя эту команду и скопировать его на моем устройстве:HTTPS-сервер на устройстве Android с использованием NanoHttpd

keytool -genkey -keystore key.keystore -storepass keypass -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider 

Я написал следующий код:

keyStore = KeyStore.getInstance("BKS"); 
keyStore.load(stream, keyStorePwd.toCharArray()); 
keyManagerFactory = KeyManagerFactory 
      .getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
keyManagerFactory.init(keyStore, keyStorePwd.toCharArray()); 
SSLContext sc = SSLContext.getInstance("TLS"); 
sc.init(keyManagerFactory.getKeyManagers(), null, null); 
server.makeSecure(sc.getServerSocketFactory()); 
server.start(); 

Я испытал это на Chrome 38 и 42 с «Минимальный SSL/TLS "установлен флаг" SSLv3 ". Но когда я хочу подключиться к серверу, я получаю ошибку «ERR_SSL_VERSION_OR_CIPHER_MISMATCH».

Я пробовал разные экземпляры протокола (SSL/TLS), на нескольких компьютерах и в браузерах. Я попробовал NanoHttpd SSLServerSocketFactory метод. Но ошибка такая же.

я уже смотрел на некоторых образцах в том числе: https://github.com/NanoHttpd/nanohttpd/issues/139

Кто-нибудь есть какие-либо комментарии по этому поводу?

+0

На какой версии Android вы выполняете сервер? – Robert

+0

Это телефон LG VS985 с Android-версией 5.0.1 – user3183066

+0

вы получаете это для работы? – KVISH

ответ

5

После продолжительного труда у меня это получилось!

Вот мой (рабочий) Код:

// I placed this block right below my class declaration so it runs 
// as soon as the class is defined. (this is for localhost testing ONLY!!!!)  
static { 
    //for localhost testing only 
    javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
    new javax.net.ssl.HostnameVerifier(){ 

     public boolean verify(String hostname, 
       javax.net.ssl.SSLSession sslSession) { 
      if (hostname.equals("localhost")) { 
       return true; 
      } 
      return false; 
     } 
    }); 
} 

// then in an init function, I set it all up here 
this.secureAppServer = new NanoHTTPD(9043); 
File f =new File("src/main/resources/key001.jks"); 
System.setProperty("javax.net.ssl.trustStore", f.getAbsolutePath()); 
this.secureAppServer.setServerSocketFactory(new SecureServerSocketFactory(NanoHTTPD.makeSSLSocketFactory("/" +f.getName(), "myawesomepassword".toCharArray()), null)); 

this.secureAppServer.start(); 

Вот фактический NanoHttpd Тестовый пример, который иллюстрирует, как именно его сделали Nano стиль.

package fi.iki.elonen; 

import java.io.File; 

/* 
* #%L 
* NanoHttpd-Core 
* %% 
* Copyright (C) 2012 - 2015 nanohttpd 
* %% 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met: 
* 
* 1. Redistributions of source code must retain the above copyright notice, this 
* list of conditions and the following disclaimer. 
* 
* 2. Redistributions in binary form must reproduce the above copyright notice, 
* this list of conditions and the following disclaimer in the documentation 
* and/or other materials provided with the distribution. 
* 
* 3. Neither the name of the nanohttpd nor the names of its contributors 
* may be used to endorse or promote products derived from this software without 
* specific prior written permission. 
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
* OF THE POSSIBILITY OF SUCH DAMAGE. 
* #L% 
*/ 

import java.io.IOException; 
import java.util.Arrays; 

import javax.net.ssl.SSLServerSocket; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.methods.HttpTrace; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.junit.After; 
import org.junit.Assert; 
import org.junit.Before; 
import org.junit.Test; 

import fi.iki.elonen.NanoHTTPD.SecureServerSocketFactory; 

public class SSLServerSocketFactoryTest extends HttpServerTest { 

    @Test 
    public void testSSLConnection() throws ClientProtocolException, IOException { 
     DefaultHttpClient httpclient = new DefaultHttpClient(); 
     HttpTrace httphead = new HttpTrace("https://localhost:9043/index.html"); 
     HttpResponse response = httpclient.execute(httphead); 
     HttpEntity entity = response.getEntity(); 
     Assert.assertEquals(200, response.getStatusLine().getStatusCode()); 

     Assert.assertEquals(9043, this.testServer.getListeningPort()); 
     Assert.assertTrue(this.testServer.isAlive()); 
    } 

    @Test 
    public void testCreatePassesTheProtocolsToServerSocket() throws IOException { 
     // first find the supported protocols 
     SecureServerSocketFactory secureServerSocketFactory = new SecureServerSocketFactory(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray()), null); 
     SSLServerSocket socket = (SSLServerSocket) secureServerSocketFactory.create(); 
     String[] protocols = socket.getSupportedProtocols(); 

     // remove one element from supported protocols 
     if (protocols.length > 0) { 
      protocols = Arrays.copyOfRange(protocols, 0, protocols.length - 1); 
     } 

     // test 
     secureServerSocketFactory = new SecureServerSocketFactory(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray()), protocols); 
     socket = (SSLServerSocket) secureServerSocketFactory.create(); 
     Assert.assertArrayEquals("Enabled protocols specified in the factory were not set to the socket.", protocols, socket.getEnabledProtocols()); 
    } 

    @Before 
    public void setUp() throws Exception { 
     System.setProperty("javax.net.ssl.trustStore", new File("src/test/resources/keystore.jks").getAbsolutePath()); 
     this.testServer = new TestServer(9043); 
     this.testServer.setServerSocketFactory(new SecureServerSocketFactory(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray()), null)); 
     this.tempFileManager = new TestTempFileManager(); 
     this.testServer.start(); 
     try { 
      long start = System.currentTimeMillis(); 
      Thread.sleep(100L); 
      while (!this.testServer.wasStarted()) { 
       Thread.sleep(100L); 
       if (System.currentTimeMillis() - start > 2000) { 
        Assert.fail("could not start server"); 
       } 
      } 
     } catch (InterruptedException e) { 
     } 
    } 

    @After 
    public void tearDown() { 
     this.testServer.stop(); 
    } 
} 
+1

ОДНА ПРИМЕЧАНИЕ. Нано пытается загрузить хранилище ключей в качестве потока ресурсов, поэтому KeyStore ДОЛЖЕН находиться в src/main/resources (именно поэтому я установил это как жесткий путь). Похоже, это функция безопасности;). – Decoded

+1

Остерегайтесь публичной публикации ваших паролей –

+0

, вы имеете в виду, что вы сохранили папку 'res' файла? Я не могу найти файл '.jks'. – KVISH