2011-07-30 160 views
0

我正在使用SSL进行服务器和客户端之间的TCP传输的C#项目。我使用makecert程序创建了证书文件,但它仅在生成它的计算机上运行(尽管我已安装.cer文件)。我几乎可以肯定,问题出在我投入的命令参数,但我查了很多组合,没有(despit以下)工作SSL证书生成

.CER文件只用于加密传历程
makecert -r -pe -n "CN=This is my certificate" -ss my -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 ca.cer 

。我不使用PKI。此外,使用SSL是“无用的要求” - 它必须被使用,仅供使用。不应考虑任何安全问题。

如果有人应该回答我,如何创建证书,这将可以使用X509Certificate.CreateFromCertFile方法我会很高兴。

+1

你需要SSH或SSL测试?这是两种不同的协议。 –

+0

当前我正在使用System.Net.Security.SslStream类,它是AuthenticateAsServer(X509Certificate)方法 –

+0

当您说'我已安装.cer文件' - 何处?您需要将其安装到CA商店,否则它将不会被其他计算机信任。 –

回答

2

如果您控制将使用这些证书的所有计算机,则可以创建所有机器都信任的CA,然后根据该证书颁发证书。

这是我的批处理文件。第一个创建CA证书:

:// Create a self-signed certificate (-r), 
:// with an exportable private key (-pe), 
:// using SHA1 (-r), for signing (-sky signature). 
:// The private key is written to a file (-sv). 
makecert -r -pe -n "CN=My Root Authority" -ss CA^
    -sr CurrentUser -a sha1 -sky signature -cy authority^
    -sv CA.pvk CA.cer 

导入.CER文件到这些机器上的CA证书存储区必须连接到服务器(他们必须信任CA):

:// Import that certificate into the 
:// "Trusted Root Certification Authorities" store. 
certutil -user -addstore Root CA.cer 

这一个创建一个服务器证书:

:// Create a server certificate, with an exportable private key (-pe), 
:// using SHA1 (-r) for key exchange (-sky exchange). 
:// It can be used as an SSL server certificate (-eku 1.3.6.1.5.5.7.3.1). 
:// The issuing certificate is in a file (-ic), as is the key (-iv). 
:// Use a particular crypto provider (-sp, -sy). 
makecert -pe -n "CN=server.example.com" -a sha1^
    -sky exchange -eku 1.3.6.1.5.5.7.3.1 
    -ic CA.cer -iv CA.pvk^
    -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12^
    -sv server.pvk server.cer 
pvk2pfx -pvk server.pvk -spc server.cer -pfx server.pfx 

安装.pfx文件,然后拿到C#服务器代码使用它。这留给读者作为练习。

0

您需要获得有效的证书。 makecert命令生成的仅用于测试,并不适用于其他系统。

+0

但我应该如何实现这个:)程序仅供学术使用,所以我不想与CA合作。我怎样才能生成有效的证书,可以在两台不同的机器上使用? –

+0

如果您正确安装它,它会。它仍然只能用于测试或内部目的。 –

+0

你是什么意思,说“正确”? –

3

感谢罗杰,我发现您的博客,并设法得到它的工作,把一个包装围绕它,所以它很容易使用,我也设法设置的友好名称的证书

using System; 
using System.Collections.Generic; 
using System.Security.Cryptography.X509Certificates; 
using System.Diagnostics; 

public class SSLCertificateCreator 
{ 
    public static string RunDosCommand(string Cmd, string Arguments) 
    {//Executes a Dos command in the current directory and then returns the result 
     string TestMessageText = ""; 
     string filePath = Environment.CurrentDirectory; 
     ProcessStartInfo pi = new ProcessStartInfo() 
     { 
      FileName = filePath + "\\" + Cmd, 
      Arguments = Arguments + " ", 
      RedirectStandardOutput = true, 
      UseShellExecute = false, 
      CreateNoWindow = false 
     }; 
     try 
     { 
      using (Process p = Process.Start(pi)) 
      { 
       p.WaitForExit(); 
       TestMessageText = p.StandardOutput.ReadToEnd(); 
       return TestMessageText; 
      } 
     } 
     catch (Exception Ex) 
     { 
      return "ERROR :" +Ex.Message; 
     } 
    } 

    public static bool MakeCACertificate(string RootCertificateName, string FriendlyName) 
    {//Make a CA certificate but only if we don't already have one and then sets the friendly name 
     if (FindCertificate("Root", RootCertificateName, OpenFlags.ReadOnly) != null) return false; //We already have this root certificate 
     string Arguments="-pe -n \"CN=" + RootCertificateName + "\" -ss Root -sr CurrentUser -a sha1 -sky signature -r \"" + RootCertificateName + ".cer\" -m 12"; 
     string Result=RunDosCommand("makecert", Arguments); 
     X509Certificate2 Cert = FindCertificate("Root", RootCertificateName, OpenFlags.ReadWrite); 
     if (Cert == null || !Result.ToLower().StartsWith("succeeded")) return false; 
     Cert.FriendlyName = FriendlyName; 
     return true; 
    } 


    public static bool MakeSignedCertificate(string RootCertificateName, string CertificateName, string FriendlyName) 
    {//Makes a signed certificate but only if we have the root certificate and then sets the friendly name 
     if (FindCertificate("Root", RootCertificateName, OpenFlags.ReadOnly) == null) return false; //We must have a valid root-certificate first 
     if (FindCertificate("my",CertificateName, OpenFlags.ReadOnly)!=null) return false;//Nope we alrady have this signed certificate 
     string Arguments = "-pe -n \"CN=" + CertificateName + "\" -ss my -sr CurrentUser -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in \"" + RootCertificateName + "\" -is Root -ir CurrentUser -sp \"Microsoft RSA SChannel Cryptographic Provider\" -sy 12 \"" + CertificateName + ".cer\" -m 12"; 
     string Result = RunDosCommand("makecert", Arguments); 
     X509Certificate2 Cert = FindCertificate("my", CertificateName, OpenFlags.ReadWrite); 
     if (Cert==null || !Result.ToLower().StartsWith("succeeded")) return false; 
     Cert.FriendlyName = FriendlyName; 
     return true; 
    } 

    private static X509Certificate2 FindCertificate(string Store, string Name, OpenFlags Mode) 
    {//Look to see if we can find the certificate store 
     X509Store store = new X509Store(Store,StoreLocation.CurrentUser); 
     store.Open(Mode); 
     foreach (X509Certificate2 Cert in store.Certificates) 
     { 
      if (Cert.Subject.ToLower() =="cn="+ Name.ToLower()) 
       return Cert;//Yep found it 
     } 
     return null; 
    } 
} 

样品使用率

SSLCertificateCreator.MakeCACertificate(“DavesRoot”,“Nice Name”); SSLCertificateCreator.MakeSignedCertificate(“DavesRoot”,“Daves Signed Certificate5”,“Nice Name”);

makecert.exe必须在BIN/Release或Debug目录的代码工作,这段代码只曾经在Windows 8

+0

如果您使用C#生成证书,那么您应该查看Bouncy Castle。我有一系列有关该主题的博客文章:http://blog.differentpla.net/tag/bouncy-castle –