我的目标是在 Java 服务器和用 C# 编写的客户端之间建立安全通信。
Java 服务器代码:
System.setProperty("javax.net.ssl.keyStore","cert/mySrvKeystore");
System.setProperty("javax.net.ssl.keyStorePassword","myPassword");
SSLServerSocketFactory sslserversocketfactory =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket = = (SSLServerSocket) sslserversocketfactory.createServerSocket(2389);
while(true) {
System.err.println("server w8 new connection");
try {
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
//sslsocket.startHandshake();
in = sslsocket.getInputStream();
out = sslsocket.getOutputStream();
out.flush();
String response = new String(receiveMessage());
while (response != "end") {
System.out.println("Server recv="+response);
response = new String(receiveMessage());
sendMessage(("echo="+response).getBytes());
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
和用 c# 编写的客户端:
client = new TcpClient() { SendTimeout = 5000, ReceiveTimeout = 5000 };
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(host), port);
client.Connect(serverEndPoint);
client.NoDelay = true;
Console.WriteLine("Client connected.");
// Create an SSL stream that will close the client's stream.
SslStream sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null);
// The server name must match the name on the server certificate.
try
{
sslStream.AuthenticateAsClient("someName");
}
catch (AuthenticationException error)
{
Console.WriteLine("Exception: {0}", error.Message);
if (error.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", error.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
client.Close();
return;
}
ASCIIEncoding ascii = new ASCIIEncoding();
SendData(ascii.GetBytes("Hello World"));
和
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers.
return false;
}
我得到以下错误:在 c# 中
A first chance exception of type "System.Security.Authentication.AuthenticationException" occurred in System.dll
Certificate error: RemoteCertificateChainErrors
Exception: The remote certificate is invalid according to the validation procedure.
Authentication failed - closing the connection.
我知道问题可能是我使用了不同类型的证书,但我不知道如何在 java 中使用 X509Certificate 制作标准 sslServerSocket。有人可以通过很好的例子帮助我,或者给我一些如何实现目标的建议吗?
附言我一直在寻找 bouncycaSTLe 库,因为它同时具有 java 和 c# 实现,但我想使用标准库和语言的内置功能。</p>
最佳答案
从您的示例来看,您似乎不需要以编程方式生成证书和私钥。您可以使用 keytool
在服务器 keystore 中生成证书:
keytool -genkey -alias myalias -keystore mykeystore.jks -dname "CN=www.example.com"
或者更好的是,如果您使用 Java 7 的 keytool
,也可以使用 SAN 扩展:
keytool -genkey -alias myalias -keystore mykeystore.jks -dname "CN=www.example.com" -ext san=dns:www.example.com
这里,www.example.com
是客户端看到的主机名。您可以在主题 DN (dname
) 中添加其他内容,但要确保 CN
是主机名。
生成后,使用以下方式导出您的自签名证书:
keytool -export myservercert.crt -alias myalias -keystore mykeystore.jks
然后您应该能够将其作为受信任的证书导入到您的 Windows 证书存储区中,以便从 C# 中使用。
关于c# - Java 和 C# 应用程序之间的 SSL 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9587762/