android - "NO SERVER CERTIFICATE FOUND"在 Android 上使用 HTTPS ReSTLet 服务器

标签 android ssl https ssl-certificate restlet

我正在使用 ReSTLet 2.3.2 和 Android 4.4.4。

我之前使用 ReSTLet 和 HTTP 成功运行了一个 Android 服务器应用程序,但现在,我在尝试使用 HTTPS 时遇到了问题。

尝试使用我的 Chrome 浏览器连接到此服务器返回 ERR_CONNECTION_CLOSE 错误。如您所见,logcat 中有一个异常,指出未找到服务器证书。所以,我想我的错误是围绕证书生成......

这是我的 Android 服务器代码:

// Creating a minimal Restlet returning "Hello World"
Restlet restlet = new Restlet() {
    @Override
    public void handle(Request request, Response response) {
        response.setEntity("Hello World!", MediaType.TEXT_PLAIN);
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final File keystore3 = new File("/storage/sdcard0/qlinks.bks");
    Log.d(TAG, "Keystore3 exists: " + keystore3.exists());
    Log.d(TAG, "Keystore3 can read: " + keystore3.canRead());

    Engine.getInstance().getRegisteredServers().add(new HttpsServerHelper(null));
    Engine.setLogLevel(Level.FINEST);

    // Create a new Component.
    Component component = new Component();

    // Add a new HTTPS server listening on port 8080
    Server server = component.getServers().add(Protocol.HTTPS, 8080);  
    Series<Parameter> parameters = server.getContext().getParameters();
    parameters.add("sslContextFactory", "org.restlet.engine.ssl.DefaultSslContextFactory");
    parameters.add("keyStorePath", "/storage/sdcard0/qlinks.bks");
    parameters.add("keyStorePassword", "password");
    parameters.add("keyPassword", "password");
    parameters.add("keyStoreType", "BKS");

    parameters.add("keyManagerAlgorithm", KeyManagerFactory.getDefaultAlgorithm());

    // Attach the sample application.
    component.getDefaultHost().attach("/test", restlet);

    // Start the component.
    try {
        server.start();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

这是 logcat 输出:

I/System.out(11955): debugger has settled (1315)
D/q_links.RestletServer(11955): Keystore3 exists: true
D/q_links.RestletServer(11955): Keystore3 can read: true
D/dalvikvm(11955): GC_FOR_ALLOC freed 249K, 3% free 9142K/9416K, paused 39ms, total 40ms
W/System.err(11955): Starting the internal [HTTPS/1.1] server on port 8080
[...]
W/System.err(11955): NIO controller selected 1 key(s) !
W/System.err(11955): ReadableSocketChannel created from: java.nio.SocketChannelImpl@424e2cc0,Interest= NONE , Ready=NONE , Canceling=false. Registration: Interest= NONE , Ready=NONE , Canceling=false
W/System.err(11955): ReadableSslChannel created from: org.restlet.ext.nio.internal.connection.Connection$1@424e5dc0. Registration: Interest= NONE , Ready=NONE , Canceling=false
W/System.err(11955): Connection state (old | new) : OPENING | OPEN
W/System.err(11955): InboundWay#setMessageState: START
W/System.err(11955): InboundWay#setIoState: INTEREST
W/System.err(11955): Old connection NIO interest: Interest= NONE , Ready=NONE , Canceling=false
W/System.err(11955): New connection NIO interest: Interest= READ , Ready=NONE , Canceling=false
W/System.err(11955): Connection from "/192.168.2.77:56441" accepted. New count: 1
W/System.err(11955): helper.control()
W/System.err(11955): controlConnections()
W/System.err(11955): Connection status: OPEN | true | Interest= READ , Ready=NONE , Canceling=false | org.apache.harmony.xnet.provider.jsse.SSLEngineImpl@420f5280 | null
W/System.err(11955): registerKeys()
W/System.err(11955): Registering new NIO interest with selector: Interest= READ , Ready=NONE , Canceling=false
W/System.err(11955): updateKeys()
W/System.err(11955): selectKeys(60000)
W/System.err(11955): NIO controller about to sleep 60000 ms, selecting among 2 keys...
W/System.err(11955): NIO controller selected 2 key(s) !
W/System.err(11955): ReadableSocketChannel created from: java.nio.SocketChannelImpl@424f8670,Interest= NONE , Ready=NONE , Canceling=false. Registration: Interest= NONE , Ready=NONE , Canceling=false
W/System.err(11955): ReadableSslChannel created from: org.restlet.ext.nio.internal.connection.Connection$1@424f8cd0. Registration: Interest= NONE , Ready=NONE , Canceling=false
W/System.err(11955): Connection state (old | new) : OPENING | OPEN
W/System.err(11955): InboundWay#setMessageState: START
W/System.err(11955): InboundWay#setIoState: INTEREST
W/System.err(11955): Old connection NIO interest: Interest= NONE , Ready=NONE , Canceling=false
W/System.err(11955): New connection NIO interest: Interest= READ , Ready=NONE , Canceling=false
W/System.err(11955): Connection from "/192.168.2.77:56442" accepted. New count: 2
W/System.err(11955): NIO selection detected for key: Interest= READ , Ready=NONE , Canceling=false
W/System.err(11955): Server connection (state | empty | registration): OPEN | true | Interest= READ , Ready=READ , Canceling=false | org.apache.harmony.xnet.provider.jsse.SSLEngineImpl@420f5280 | null
W/System.err(11955): InboundWay#setIoState: PROCESSING
W/System.err(11955): Processing IO for inbound way: PROCESSING, START, java.nio.ByteArrayBuffer[position=0,limit=16384,capacity=16384], FILLING, true
W/System.err(11955): Beginning process of buffer java.nio.ByteArrayBuffer[position=0,limit=16384,capacity=16384], FILLING, true
W/System.err(11955): 0 bytes drained from buffer at pre-processing, 16384 remaining bytes
W/System.err(11955): Filling buffer java.nio.ByteArrayBuffer[position=0,limit=16384,capacity=16384], FILLING, true
W/System.err(11955): Beginning process of buffer java.nio.ByteArrayBuffer[position=0,limit=18437,capacity=18437], FILLING, true
W/System.err(11955): 0 bytes drained from buffer at pre-processing, 18437 remaining bytes
W/System.err(11955): Filling buffer java.nio.ByteArrayBuffer[position=0,limit=18437,capacity=18437], FILLING, true
W/System.err(11955): 179 bytes filled into buffer
W/System.err(11955): Filling buffer java.nio.ByteArrayBuffer[position=179,limit=18437,capacity=18437], FILLING, false
W/System.err(11955): Draining buffer java.nio.ByteArrayBuffer[position=0,limit=179,capacity=18437], DRAINING, false
W/System.err(11955): SSL engine result: SSLEngineReport: Status = OK  HandshakeStatus = NEED_TASK
W/System.err(11955):                  bytesConsumed = 179 bytesProduced = 0
W/System.err(11955): SSL connection: OPEN | true | Interest= READ , Ready=READ , Canceling=false | org.apache.harmony.xnet.provider.jsse.SSLEngineImpl@420f5280 | null
W/System.err(11955): 179 bytes drained from buffer, 0 remaining bytes
W/System.err(11955): Draining buffer java.nio.ByteArrayBuffer[position=179,limit=179,capacity=18437], DRAINING, true
W/System.err(11955): Filling buffer java.nio.ByteArrayBuffer[position=0,limit=18437,capacity=18437], FILLING, true
W/System.err(11955): Ending process of buffer java.nio.ByteArrayBuffer[position=0,limit=18437,capacity=18437], FILLING, true. Result: 179, try again: false, can loop: true, total filled: 179
W/System.err(11955): Handling SSL result: OK
W/System.err(11955): Handling SSL handshake: NEED_TASK
W/System.err(11955): InboundWay#setIoState: IDLE
W/System.err(11955): Running delegated tasks...
W/System.err(11955): 179 bytes filled into buffer
D/dalvikvm(11955): GC_FOR_ALLOC freed 245K, 3% free 12858K/13128K, paused 44ms, total 44ms
W/System.err(11955): Done running delegated tasks
W/System.err(11955): Ending process of buffer java.nio.ByteArrayBuffer[position=0,limit=16384,capacity=16384], FILLING, true. Result: 0, try again: true, can loop: false, total filled: 179
W/System.err(11955): Handling SSL result: OK
W/System.err(11955): Handling SSL handshake: NEED_WRAP
W/System.err(11955): OutboundWay#setIoState: READY
W/System.err(11955): NIO controller woke up
W/System.err(11955): Handling SSL result: OK
W/System.err(11955): Handling SSL handshake: NEED_WRAP
W/System.err(11955): Inbound way selected. Done for : IDLE, START, java.nio.ByteArrayBuffer[position=0,limit=16384,capacity=16384], FILLING, true
W/System.err(11955): Entering into a connection READY loop
W/System.err(11955): Processing IO for outbound way: READY, IDLE, java.nio.ByteArrayBuffer[position=0,limit=16384,capacity=16384], FILLING, true
W/System.err(11955): Beginning process of buffer java.nio.ByteArrayBuffer[position=0,limit=16384,capacity=16384], FILLING, true
W/System.err(11955): Beginning process of buffer java.nio.ByteArrayBuffer[position=0,limit=18437,capacity=18437], FILLING, true
W/System.err(11955): 0 bytes drained from buffer at pre-processing, 18437 remaining bytes
W/System.err(11955): Filling buffer java.nio.ByteArrayBuffer[position=0,limit=18437,capacity=18437], FILLING, true
W/System.err(11955): Error while processing a connection
W/System.err(11955): javax.net.ssl.SSLException: Error occured in delegated task:javax.net.ssl.SSLHandshakeException: NO SERVER CERTIFICATE FOUND
W/System.err(11955):    at org.apache.harmony.xnet.provider.jsse.HandshakeProtocol.fatalAlert(HandshakeProtocol.java:319)
W/System.err(11955):    at org.apache.harmony.xnet.provider.jsse.HandshakeProtocol.wrap(HandshakeProtocol.java:271)
W/System.err(11955):    at org.apache.harmony.xnet.provider.jsse.SSLEngineImpl.wrap(SSLEngineImpl.java:694)
W/System.err(11955):    at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:462)
W/System.err(11955):    at org.restlet.ext.nio.internal.channel.WritableSslChannel.onFill(WritableSslChannel.java:125)
W/System.err(11955):    at org.restlet.ext.nio.internal.buffer.Buffer.process(Buffer.java:593)
W/System.err(11955):    at org.restlet.ext.nio.internal.channel.WritableBufferedChannel.write(WritableBufferedChannel.java:118)
W/System.err(11955):    at org.restlet.ext.nio.internal.channel.WritableSslChannel.write(WritableSslChannel.java:143)
W/System.err(11955):    at org.restlet.ext.nio.internal.buffer.Buffer.drain(Buffer.java:333)
W/System.err(11955):    at org.restlet.ext.nio.internal.way.OutboundWay.onDrain(OutboundWay.java:257)
W/System.err(11955):    at org.restlet.ext.nio.internal.way.HttpsServerOutboundWay.preProcess(HttpsServerOutboundWay.java:81)
W/System.err(11955):    at org.restlet.ext.nio.internal.buffer.Buffer.process(Buffer.java:528)
W/System.err(11955):    at org.restlet.ext.nio.internal.way.Way.processIoBuffer(Way.java:498)
W/System.err(11955):    at org.restlet.ext.nio.internal.way.OutboundWay.processIoBuffer(OutboundWay.java:463)
W/System.err(11955):    at org.restlet.ext.nio.internal.way.Way.onSelected(Way.java:451)
W/System.err(11955):    at org.restlet.ext.nio.internal.connection.Connection.onSelected(Connection.java:664)
W/System.err(11955):    at org.restlet.util.SelectionRegistration.onSelected(SelectionRegistration.java:316)
W/System.err(11955):    at org.restlet.ext.nio.internal.controller.ConnectionController.onSelected(ConnectionController.java:213)
W/System.err(11955):    at org.restlet.ext.nio.internal.controller.ServerConnectionController.onSelected(ServerConnectionController.java:109)
W/System.err(11955):    at org.restlet.ext.nio.internal.controller.ConnectionController.selectKeys(ConnectionController.java:302)
W/System.err(11955):    at org.restlet.ext.nio.internal.controller.ConnectionController.doRun(ConnectionController.java:165)
W/System.err(11955):    at org.restlet.ext.nio.internal.controller.Controller.run(Controller.java:152)
W/System.err(11955):    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
W/System.err(11955):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
W/System.err(11955):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
W/System.err(11955):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
W/System.err(11955):    at java.lang.Thread.run(Thread.java:841)
W/System.err(11955): Caused by: org.apache.harmony.xnet.provider.jsse.AlertException: javax.net.ssl.SSLHandshakeException: NO SERVER CERTIFICATE FOUND
W/System.err(11955):    at org.apache.harmony.xnet.provider.jsse.HandshakeProtocol.fatalAlert(HandshakeProtocol.java:308)
W/System.err(11955):    at org.apache.harmony.xnet.provider.jsse.ServerHandshakeImpl.processClientHello(ServerHandshakeImpl.java:459)
W/System.err(11955):    at org.apache.harmony.xnet.provider.jsse.ServerHandshakeImpl$1.run(ServerHandshakeImpl.java:123)
W/System.err(11955):    at org.apache.harmony.xnet.provider.jsse.DelegatedTask.run(DelegatedTask.java:36)
W/System.err(11955):    at org.restlet.ext.nio.internal.connection.SslConnection$1.run(SslConnection.java:417)
W/System.err(11955):    ... 3 more
W/System.err(11955): Caused by: javax.net.ssl.SSLHandshakeException: NO SERVER CERTIFICATE FOUND
W/System.err(11955):    ... 8 more
W/System.err(11955): Closing connection to /192.168.2.77:56441 immediately
W/System.err(11955): InboundWay#setMessageState: IDLE
W/System.err(11955): OutboundWay#setIoState: IDLE
W/System.err(11955): Connection state (old | new) : OPEN | CLOSED
W/System.err(11955): Connection to /192.168.2.77:56441 is now closed

这是我生成证书的方式:

> keytool -genkey -alias qlinks -keystore qlinks.keystore -validity 365
> keytool -export -alias qlinks -keystore qlinks.keystore -file qlinks.cer
> keytool -import -alias qlinks -file qlinks.cer -keystore qlinks.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath ~/Downloads/bcprov-jdk15on-146.jar
> adb push qlinks.bks /storage/sdcard0/

这是我从我的 Android 项目中输出到我的 /libs 目录中的 jar:

android-support-v4.jar
org.jsslutils.jar
org.restlet.ext.nio.jar
org.restlet.jar

最佳答案

正如我所怀疑的,我的证书没有正确生成。

我很确定有更简单的方法,但这是我所做的(在另一个 answer 的帮助下):

> openssl genrsa -des3 -passout pass:1 -out qlinks.pass.key 2048
> openssl rsa -passin pass:1 -in qlinks.pass.key -out qlinks.key
> openssl req -new -key qlinks.key -out qlinks.csr
> openssl x509 -req -days 365 -in qlinks.csr -signkey qlinks.key -out qlinks.crt
> keytool -keystore keystore -import -alias jetty -file qlinks.crt -trustcacerts
> openssl pkcs12 -inkey qlinks.key -in qlinks.crt -export -out qlinks.pkcs12
> keytool -importkeystore -srckeystore qlinks.pkcs12 -srcstoretype PKCS12 -destkeystore keystore

接下来,我必须使用一个名为 portecle 的简洁工具至 convert my JKS keystore (keystore 文件)到 BKS,因为 Android 仅支持 BouncyCaSTLe keystore ,AFAIK。

最后,我将文件推送到目标:

adb push keystore /storage/sdcard0/qlinks.bks

关于android - "NO SERVER CERTIFICATE FOUND"在 Android 上使用 HTTPS ReSTLet 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30512696/

相关文章:

php - 在 PHP 中响应来自客户端站点的 Https POST 请求

android - ImageView 加载高分辨率图像质量很差

android - 我应该使用什么 Android 设备来开发我的 Android 应用程序?

apache - 400 Bad Request 您正在向启用 SSL 的服务器端口 kubernetes pod 使用普通 HTTP

java - 如何获取在 SSL 握手中生成的对称 key ?

当 DNS A 直接指向不同服务器上的虚拟主机时,SSL 证书安装在哪里?

android - 手机屏幕内的可见地理点

android - 安全异常 : not allowed to perform OP_READ_PHONE_STATE

android - 无法从我的 Android 模拟器访问 HTTPS

带有 Visual Studio 2015 的 ASP.NET 网站 SSL