"NO SERVER CERTIFICATE FOUND" 在 Android 上使用 HTTPS Restlet 服务器
"NO SERVER CERTIFICATE FOUND" with HTTPS Restlet server on Android
我正在使用 Restlet 2.3.2 和 Android 4.4.4。
我之前成功地 运行 一个 Android 服务器应用程序使用 Restlet 和 HTTP,但现在,我 运行 在尝试使用 HTTPS 做同样的事情时遇到了问题。
尝试使用我的 Chrome 浏览器连接到此服务器 returns 出现 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@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@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.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.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
目录中的罐子:
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 to convert my JKS keystore 的简洁工具(keystore
文件)来 BKS,因为 Android 仅支持 BouncyCastle 密钥库,AFAIK。
最后,我将文件推送到目标:
adb push keystore /storage/sdcard0/qlinks.bks
我正在使用 Restlet 2.3.2 和 Android 4.4.4。
我之前成功地 运行 一个 Android 服务器应用程序使用 Restlet 和 HTTP,但现在,我 运行 在尝试使用 HTTPS 做同样的事情时遇到了问题。
尝试使用我的 Chrome 浏览器连接到此服务器 returns 出现 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@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@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.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.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
目录中的罐子:
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 to convert my JKS keystore 的简洁工具(keystore
文件)来 BKS,因为 Android 仅支持 BouncyCastle 密钥库,AFAIK。
最后,我将文件推送到目标:
adb push keystore /storage/sdcard0/qlinks.bks