开发者

SSL certificate generation

I am working on C# project where tcp transmition between server and client is made using SSL. I created certificate file with makecert program, but it works only on computer where it was generated (although I have i开发者_如何学Cnstalled .cer file). I am almost sure, that the problem lies in parameters which I put into command, but I checked many combinations and none (despit following) worked

makecert -r -pe -n "CN=This is my certificate" -ss my -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 ca.cer

.cer file is used only for ciphering transmition. I don't use PKI. Furthermore using SSL is "dead requirement" - it must be used, just for be used. Any security issues shouldn't be considered.

If anyone should answer me, how to create certificate, that will be able to be used by X509Certificate.CreateFromCertFile method I would be delighted.


Thanks Roger I found your blog and managed to get it working and put a wrapper around it so it's easy to use and I also managed to set the friendly-Name on the certificates

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;
    }
}

Sample useage

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

makecert.exe needs to be in the Bin/Release or Debug directory for the code to work and this code has only ever been tested on Windows-8


If you control all of the machines that will use these certificates, you can create a CA that's trusted by all of the machines, and then issue certificates based on that.

Here are my batch files. The first one creates the CA certificate:

:// 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

Import the .CER file into the CA certificate store on those machines that must connect to the server (they must trust the CA):

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

This one creates a server certificate:

:// 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

Install the .pfx file, and then get the C# server code to use it. This is left as an exercise for the reader.


You need to get a valid certificate. The one generated by makecert command is only for testing and wont work on other systems.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜