В началото... Тази програма е само 4-забавна и никога няма да бъде публикувана. Това е само за тестване на Sockets, така че не се интересувайте от сигурността на тази връзка. Кодирах малък месинджър, където можете да въведете съобщение в текстово поле и то ще бъде изпратено до сървъра и от сървъра до всички клиенти. Дотук добре. Просто за забавление исках да използвам SSL за тази връзка. Но когато се опитвам да се свържа със сървърния сокет, той връща RemoteCertificateNameMismatch при ValidateServerCertificate. След като добавих някои съобщения за отстраняване на грешки, открих, че Sslstream.LocalCertificate е null. Как мога да поправя този липсващ сертификат? Използвам самоподписан сертификат.
Моля, помогнете, ето моя код... и да... съжалявам за лошия ми английски :/ :
C# клиент
[...]
public bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
//sslPolicyErrors returns RemoteCertificateNameMismatch
return true; //Code shortened
}
public X509CertificateCollection getCertificates()
{
X509CertificateCollection cCollection = new X509CertificateCollection();
cCollection.Add(getCertificate());
return cCollection;
}
private X509Certificate getCertificate()
{
string Certificate = "D:/Wlad/Programmierung/Zertifikat/CA/CertificateAuthority.crt";
string ClientCertificatePassword = "...";
return new X509Certificate(Certificate, ClientCertificatePassword);
}
public X509Certificate SelectLocalCertificate(
object sender,
string targetHost,
X509CertificateCollection localCertificates,
X509Certificate remoteCertificate,
string[] acceptableIssuers)
{
foreach(X509Certificate cer in localCertificates) {
return cer;
}
return getCertificate();
}
public void connect(String username)
{
XMLConfigManager xml = XMLConfigManager.getInstance();
String ip = xml.get("ip");
tc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ;
tc.Connect(ip, int.Parse(xml.get("port")));
networdstream = new NetworkStream(tc);
using(sslstream = new SslStream(networdstream, false, new RemoteCertificateValidationCallback(ValidateServerCertificate), new LocalCertificateSelectionCallback(SelectLocalCertificate)))
{
sslstream.AuthenticateAsClient(ip, getCertificates(), SslProtocols.Default, true);
}
sendMessage(username);
t = new Thread(new ThreadStart(checkInput));
t.Start();
tm.addThread(t);
th = new Thread(new ThreadStart(userTimer));
th.Start();
tm.addThread(th);
}
public void disconnect()
{
if(sslstream != null) {
sslstream.Close();
}
if(tc != null) {
tc.Close();
}
}
[...]
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
public void sendMessage(String s)
{
try
{
if ((s != null) && (s.Length > 0))
{
try
{
sslstream.Write(GetBytes(s));
}
catch (Exception)
{
}
}
}
catch (Exception ex)
{
endError(ex);
return;
}
}
public void userTimer()
{
Thread.Sleep(2000);
sendCommand("usercount");
th = new Thread(new ThreadStart(userTimer));
th.Start();
tm.addThread(th);
}
[...]
static String ReadMessage(SslStream sslStream)
{
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
} while (bytes != 0);
return messageData.ToString();
}
public void checkInput()
{
try
{
Form2 f2 = f1.f;
if(!isConnected()) {
t.Abort();
return;
}
String s = ReadMessage(sslstream);
if(s == null) {
t.Abort();
return;
}
CommandHandler ch = new CommandHandler();
Boolean handle = ch.handle(s, f1.f);
if (!handle) {
if (s == "Der Benutzername ist schon vergeben.")
{
endDuplicatename();
return;
}
f2.Invoke(new Action(() => f2.chat.Items.Add(s)));
f2.Invoke(new Action(() => f2.select_newest()));
}
}
finally
{
t = new Thread(new ThreadStart(checkInput));
t.Start();
tm.addThread(t);
}
}
Java Server Socket
package de.wladhd.server;
import java.net.Socket;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import de.wladhd.client.Client;
import de.wladhd.client.ClientManager;
import de.wladhd.logs.Log;
import de.wladhd.logs.LogType;
public class DateServer {
private SSLServerSocket server;
private boolean running = true;
private String keyStore = "D:/Wlad/Programmierung/Zertifikat/CA/CertificateAuthority.pfx";
private String keyStorePassword = "...";
private String keyStoreType = "PKCS12";
private String trustStore = "D:/Wlad/Programmierung/Zertifikat/CA/CertificateAuthority.pfx";
private String trustStorePassword = "...";
private String trustStoreType = "PKCS12";
public void execute() throws Exception {
//System.setProperty("javax.net.debug","all");
System.setProperty("javax.net.ssl.keyStoreType", keyStoreType);
System.setProperty("javax.net.ssl.keyStore", keyStore);
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
System.setProperty("javax.net.ssl.trustStoreType", trustStoreType);
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
//System.setProperty("javax.net.ssl.trustStore", "de.wladhd.server.Trusting");
SSLServerSocketFactory serverFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
if(serverFactory == null) {
new Log("Error occured... Server Factory == null!", LogType.ERROR);
return;
}
server = (SSLServerSocket) serverFactory.createServerSocket(9090);
running = true;
new Log("Server now running on query: " + server.getInetAddress().getHostAddress() + ":" + server.getLocalPort(), LogType.INFO);
while (running) {
try {
if(server.isClosed()) {
return;
}
new Log("Client connecting...", LogType.DEBUG);
final Socket rawsocket = server.accept();
if(!(rawsocket instanceof SSLSocket)) {
new Log("Client isnt an instance of SSLSocket!", LogType.DEBUG);
return;
}
final SSLSocket socket = (SSLSocket) rawsocket;
try {
socket.startHandshake();
} catch (Exception ex) {
}
new Log("Client - Connected: " + socket.isConnected(), LogType.DEBUG);
new Log("Client - Protocol: " + socket.getSession().getProtocol(), LogType.DEBUG);
new Log("Client - Session valid: " + socket.getSession().isValid(), LogType.DEBUG);
new Log("Client - CipherSuite: " + socket.getSession().getCipherSuite(), LogType.DEBUG);
new Log("Client - NeedClientAuth: " + socket.getNeedClientAuth(), LogType.DEBUG);
new Log("Client - WantClientAuth: " + socket.getWantClientAuth(), LogType.DEBUG);
Client c = new Client(socket);
//socket.getHandshakeSession() returns null and peer not authenticated exception...
} catch (Exception ex) {
ex.printStackTrace();
continue;
}
}
}
public void disconnect() throws Exception {
new Log("Server disconnecting...", LogType.INFO);
setRunning(false);
ClientManager.getInstance().disconnectClients();
if(server != null) {
server.close();
}
new Log("Server successfully disconnected!", LogType.INFO);
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean state) {
running = state;
}
}
Ако имате нужда от нещо, моля, кажете ми...