#android #node.js #android-studio #https #socket.io
Вопрос:
Преобразуйте мой сервер http Nodejs в самозаверяющий сертификат с сервером Nodejs (https), Сертификаты добавляются на мой сервер Nodejs отлично работают, но я хочу передать данные из сокета ввода-вывода в клиент Android с помощью https-сервера, он не работает, один месяц изо всех сил пытается завершить это, пожалуйста, помогите мне решить эту проблему с моим кодом. Пожалуйста, не используйте «Принять все коды сертификатов» в клиенте Android
Моя версия ввода — вывода сокета сервера — 2.4.1
Моя версия — реализация ввода — вывода для Android-клиента («io.socket:socket.io-клиент:1.0.0»
app.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);
}
}
}
Комментарии:
1. Для современных версий Android есть более простые способы добавить пользовательский самозаверяющий сертификат с помощью
network_security_config.xml
— просто поместите простой сертификат в качестве исходного ресурса в свой проект: developer.android.com/training/articles/…