2011-07-30 162 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 –