SSL证书生成

发布于 2024-11-27 05:47:44 字数 466 浏览 0 评论 0原文

我正在开发 C# 项目,其中服务器和客户端之间的 tcp 传输是使用 SSL 进行的。我使用 makecert 程序创建了证书文件,但它仅适用于生成它的计算机(尽管我已经安装了 .cer 文件)。我几乎可以肯定,问题出在我输入命令的参数中,但我检查了许多组合,没有一个(尽管有以下)有效的

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

.cer 文件仅用于加密传输。我不使用 PKI。此外,使用 SSL 是“死要求”——它必须被使用,只是为了被使用。不应考虑任何安全问题。

如果有人回答我如何创建证书,该证书将能够通过 X509Certificate.CreateFromCertFile 方法使用,我会很高兴。

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 installed .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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

恋竹姑娘 2024-12-04 05:47:44

谢谢罗杰,我找到了你的博客,并设法让它工作并对其进行包装,以便它易于使用,我还设法在证书上设置友好名称

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 签名证书5","好名字");

makecert.exe 需要位于 Bin/Release 或 Debug 目录中,代码才能工作,并且此代码仅在 Windows-8 上进行过测试

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

闻呓 2024-12-04 05:47:44

如果您控制将使用这些证书的所有计算机,则可以创建一个受所有计算机信任的 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# 服务器代码以使用它。这留给读者作为练习。

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.

濫情▎り 2024-12-04 05:47:44

您需要获得有效的证书。 makecert 命令生成的仅用于测试,无法在其他系统上运行。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文