C# 在c中使用带有文件和密钥的X509Certificate#
我已将证书和密码提供给接受ssl连接的服务器。我试图连接到此服务器,但身份验证失败,主要是因为我不知道如何使用提供给我的文件和密码 这是我的密码:C# 在c中使用带有文件和密钥的X509Certificate#,c#,java,ssl-certificate,x509certificate,C#,Java,Ssl Certificate,X509certificate,我已将证书和密码提供给接受ssl连接的服务器。我试图连接到此服务器,但身份验证失败,主要是因为我不知道如何使用提供给我的文件和密码 这是我的密码: X509Certificate certificate = new X509Certificate( @"c:\mySrvKeystore", KEY_PASSWORD); public static bool ValidateCertificate( object sender, X
X509Certificate certificate = new X509Certificate(
@"c:\mySrvKeystore", KEY_PASSWORD);
public static bool ValidateCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors errors)
{
if (errors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", errors);
return false;
}
public void RunClient(string address, int port)
{
Console.WriteLine("Starting client...");
var client = new TcpClient(address, port);
Console.WriteLine("Client connected.");
var stream = new SslStream(client.GetStream(),false,
ValidateCertificate, null);
try
{
stream.AuthenticateAsClient(address);
Console.WriteLine(stream.IsAuthenticated ? "Client authenticated." : "Client is not authenticated.");
//TODO constantly read from server!
}
catch (AuthenticationException ae)
{
Console.WriteLine("Exception occured: {0}", ae.Message);
if (ae.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", ae.InnerException.Message);
}
Console.WriteLine("Failed to authenticate! closing the client...");
client.Close();
return;
}
catch (Exception ex)
{
Console.WriteLine("General exception occured {0}", ex.Message);
client.Close();
return;
}
}
如您所见,我的代码中没有任何代码以某种方式告诉服务器(TcpClient或SSLStream)我确实拥有此文件和密钥
我有一个连接到服务器的Java代码,没有问题,但我还没有将其转换为c。任何帮助都会很好
String keyPassword = "123456";
// String keyPassword = "importkey";
try {
KeyManagerFactory keyManagerFactory;
keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream keyInput = new FileInputStream("c:\\mySrvKeystore");
keyStore.load(keyInput, keyPassword.toCharArray());
keyInput.close();
keyManagerFactory.init(keyStore, keyPassword.toCharArray());
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new java.security.SecureRandom());
SSLSocketFactory sslsocketfactory = sc.getSocketFactory();
this.sslsocket = (SSLSocket) sslsocketfactory.createSocket(host, port);
} catch (java.security.NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (java.security.KeyManagementException e) {
e.printStackTrace();
} catch (java.security.KeyStoreException e) {
e.printStackTrace();
} catch (java.security.cert.CertificateException e) {
e.printStackTrace();
} catch (java.security.UnrecoverableKeyException e) {
e.printStackTrace();
} finally {}
}
public void run() {
try {
InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
OutputStream outputstream = System.out;
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);
//get text from server and stuff...no deal!
更新
根据gtrig将密钥转换为p12后,现在的问题是AutheneticateAsClient
方法中的IOException:
try
{
var certificate = new X509Certificate2(@"d:\mySrvKeystore.p12", "123456");
X509Certificate2[] X509Certificates = {certificate};
var certsCollection = new X509CertificateCollection(X509Certificates);
//IO EXCEPTION HERE-->
stream.AuthenticateAsClient(address, certsCollection, SslProtocols.Ssl2, false);
Console.WriteLine(stream.IsAuthenticated ? "Client authenticated." : "Client is not authenticated.");
//TODO constantly read from server!
}
另外,当我使用
SSlProtocols.Default
时,错误是:RemoteCertificateNameMismatch,RemoteCertificateChainErrors
您应该使用AuthenticateTasClient和证书列表:
X509Certificate[] X509Certificates = { certificate };
X509CertificateCollection certsCollection = new X509CertificateCollection(X509Certificates);
sslStream.AuthenticateAsClient(address, certsCollection, SslProtocols.Default, false);
要避免证书错误,请执行以下操作:
改变
公共静态bool ValidateCertificate(
对象发送器,
X509证书,
X509链条,
SslPolicyErrors(错误)
{
if(errors==SslPolicyErrors.None)
返回true;
如果(证书!=null)
{
字符串SendingCertificateName=“”;
//List Subject=CommaText(certificate.Subject);//解码commalist
//SendingCertificateName=ExtractNameValue(主题“CN”);//获取CN=value
report=string.Format(CultureInfo.InvariantCulture,“certificatename:{0},SerialNumber:{1},{2},{3}”,certificate.Subject,certificate.GetSerialNumberString(),SendingCertificateName,ServerName);
控制台。写入线(报告);
}
WriteLine(“证书错误:{0}”,错误);
int allow=allowpolicycerrors这个答案可能不会让你一直走到那里,但它应该会让你接近
您获得了一个Java密钥库(JKS),其中包含一个私钥和相应的证书。根据您的代码打开JKS的密码是“123456”
因为JKS包含一个私钥,从您的Java代码来看,这让我相信您需要一个双向(相互)SSL连接。这基本上意味着您作为客户端对服务器进行身份验证,服务器对您进行身份验证。此JKS文件是您使用服务器的凭证
那么如何在C#中使用它呢?首先,让我们使用以下命令将JKS转换为PKCS12密钥库:
keytool -importkeystore -srckeystore mySrvKeystore -destkeystore mySrvKeystore.p12 -srcstoretype JKS -deststoretype PKCS12
现在,您可以将PKCS12文件导入Windows密钥库,这将使其易于从C#访问。或者,您可以使用以下代码将其导入对象:
X509Certificate2 cert = X509Certificate2("C:\Path\mySrvKeystore.p12", "123456");
现在,您可以使用Windows密钥库或C#中的X509Certificate2对象来建立SSL连接。从您的Java代码中,您拥有的文件是JKS密钥库。您知道它是否只包含证书,还是也包含私钥?这是单向SSL还是双向SSL(客户端身份验证)连接?@gtrig我不是很确定,但我猜它只有证书,私钥只是我代码中的密码。而且我认为它是单向连接,因为我知道服务器流数据,我不应该向服务器发送任何东西。但是从java代码判断,它可能还包括密钥,因为在Java代码。请在JKS密钥库文件上运行此命令:keytool-list-v-keystore mySrvKeystore
。查看输出是否显示“PrivateKeyEntry”或者,如果只有证书条目。代码中的密码是打开JKS密钥库文件的密码。错误来自从服务器收到的证书。指定的地址与服务器证书中的名称不匹配。您有时会在IE中收到该消息。您可以通过在ValidateCer中允许它来始终接受该消息t函数(因此始终返回true).Beter可能是为了确保证书正常。或者记录您允许的有关错误的证书。在de validatecert中放置断点时,您可以检查服务器返回的证书。在java代码中,您也只信任每个证书:trustAllCerts。您尝试过在validatecert()中将false更改为True吗?谢谢,我认为这是一个很好的步骤,至少我在转换之前尝试使用密钥时没有得到加密异常
。没有。问题是当我尝试作为客户端进行身份验证时出现了新的异常。请检查我上面的更新:而不是SslProtocols.Ssl2,尝试SslProtocols.Tls、SslProtocols.Tls11或SslProtocols.Tls12。Ssl2与客户端证书不兼容。不是真的,我希望我能以某种方式将文件发送给您:p当您执行keytool-list…
命令时,是“所有者”还是“颁发者”PrivateKeyEntry的值相同或不同?密钥库中是否列出了其他条目?感谢您提醒我不接受所有证书的问题,这就是问题所在,当我在validate方法中返回true时,它工作正常!
X509Certificate2 cert = X509Certificate2("C:\Path\mySrvKeystore.p12", "123456");