android - 使用 NodeJS 服务器和 android 客户端的自签名证书不起作用
问题描述
使用Nodejs服务器(https)将我的http Nodejs服务器转换为自签名证书,证书添加到我的Nodejs服务器中完美运行但是,我想使用https服务器将数据从socket io传递到android客户端它不起作用,一个月努力完成这请帮我完成这个问题我的代码。请不要在 android 客户端中使用接受所有证书代码
我的服务器 - socket io 版本 -- 2.4.1
我的 Android - 客户端套接字 io 版本 - 实现('io.socket:socket.io-client:1.0.0'
应用程序.js
const express = require('express')
const https = require('https')
const fs = require('fs')
const path = require('path')
const app = express()
var bodyParser = require('body-parser');
const io = require("socket.io")(https);
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.emit('CHAT',{"message":"hy"});
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
});
})
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use('/',(req,res,next) => {
res.send('Hello from SSL server!!!')
})
const sslServer = https.createServer(
{
key: fs.readFileSync(path.join(__dirname,'cert','key.pem')),
cert: fs.readFileSync(path.join(__dirname,'cert','cert.pem')),
},
app
)
sslServer.listen(3000, () => console.log("Secure Server on port 3000"))
Main3Activity.java
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
import okhttp3.OkHttpClient;
public class Main3Activity extends AppCompatActivity {
X509TrustManager trustManager;
OkHttpClient okHttpClient;
SSLSocketFactory sslSocketFactory;
String message;
final String uri = "https://192.XXX.43.XXX:3000";
private Socket mSocket;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
try {
trustManager = trustManagerForCertificates(trustedCertificatesInputStream());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
try {
okHttpClient = new OkHttpClient.Builder()
.hostnameVerifier((hostname, session) -> true)
.sslSocketFactory(sslSocketFactory, trustManager)
.connectTimeout(45, TimeUnit.SECONDS)
.readTimeout(45, TimeUnit.SECONDS)
.build();
IO.setDefaultOkHttpWebSocketFactory(okHttpClient);
IO.setDefaultOkHttpCallFactory(okHttpClient);
IO.Options opts = new IO.Options();
opts.callFactory = okHttpClient;
opts.webSocketFactory = okHttpClient;
mSocket = IO.socket(uri,opts);
mSocket.on("CHAT", onNewMessage);
mSocket.connect();
} catch (URISyntaxException e) {}
}
private Emitter.Listener onNewMessage = new Emitter.Listener() {
@Override
public void call(final Object... args) {
try {
JSONObject data = (JSONObject) args[0];
message = data.getString("message");
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("Values",message);
}
});
} catch (JSONException e) {
return;
}
}
};
private InputStream trustedCertificatesInputStream() {
return getApplicationContext().getResources().openRawResource(R.raw.cert);
}
private X509TrustManager trustManagerForCertificates(InputStream in)
throws GeneralSecurityException {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
// Put the certificates a key store.
char[] password = "password".toCharArray(); // Any password will work.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Use it to build an X509 trust manager.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
}
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream in = null; // By convention, 'null' creates an empty key store.
keyStore.load(in, password);
return keyStore;
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
解决方案
推荐阅读
- pandas - Pandas_datareader 读取符号失败(随机符号)
- javascript - Babel 创建输出目录但不转译任何文件
- python - 在 2D 列表中查找值的 Pythonic 方法?
- php - 当项目根目录与 PhpStorm 不同时如何访问资产?
- angular - 错误类型错误:无法读取未定义的 Angular Firebase 的属性“标题”
- javascript - 使用带有 javascript 的正则表达式来货币字符串转换
- reactjs - 在 React 测试库中测试依赖于 Stateful Context Providers 链的 React 组件
- reactjs - 通过 Context API 传递异步获取的数据
- c# - 在控制器中将数据作为应用程序/json发送时如何使用多个参数
- javascript - 使用“this”在翻转时更改 SVG 的填充颜色