如何使用包含主题类型为 CA 的基本约束扩展的 CA 证书创建自签名证书
How to create a self signed certificate with a CA certificate containing the basic constraint extension with subject type as CA
我正在尝试使用 azure rest 创建应用程序网关 api。我使用的是使用以下文档生成的自签名证书:
https://docs.microsoft.com/en-us/azure/application-gateway/self-signed-certificates
当我发送创建应用程序网关的请求时,出现以下错误:
不包含任何 CA 证书。 CA 证书包含主题类型为 CA 的基本约束扩展。
我曾尝试将根证书与客户端证书结合使用,但这似乎没有帮助。
该解决方案需要自动化,将 运行 来自 Windows 机器,这里是与文档相匹配的相关源代码 (C#):
Process process = null;
var processInfo = new ProcessStartInfo();
processInfo.FileName = AzureNames.OpenSSLBinaryLocation;
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
processInfo.WorkingDirectory = workingDirectory;
processInfo.Arguments = string.Format("ecparam -out {0}.key -name prime256v1 -genkey", AzureNames.CertificateRoot);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("req -new -sha256 -key {0}.key -out {0}.csr -subj \"/C=US/ST=Denver/L=Denver/O=Enterprise Architecture/OU=Enterprise Architecture/CN=site.com/emailAddress=sample@sample.com\"", AzureNames.CertificateRoot);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("x509 -req -sha256 -days 365 --extensions v3_ca -in {0}.csr -signkey contoso.key -out {0}.crt", AzureNames.CertificateRoot);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("ecparam -out {0}.key -name prime256v1 -genkey", AzureNames.CertificateClient);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("req -new -sha256 -key {0}.key -out {0}.csr -subj \"/C=US/ST=Denver/L=Denver/O=Enterprise Architecture/OU=Enterprise Architecture/CN=site.com/emailAddress=sample@sample.com\"", AzureNames.CertificateClient);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("x509 -req -in {0}.csr -CA {1}.crt -CAkey {1}.key -CAcreateserial -out {0}.crt -days 365 --extensions v3_ca -sha256", AzureNames.CertificateClient, AzureNames.CertificateRoot);
process = Process.Start(processInfo);
process.WaitForExit();
process.Close();
//combine root cert into client certificate
var rootContents = File.ReadAllText(AzureNames.CertificatesStorageLocation + @"\" + AzureNames.CertificateRoot + ".crt");
File.AppendAllText(AzureNames.CertificatesStorageLocation + @"\" + AzureNames.CertificateClient + ".crt", Environment.NewLine + rootContents);
//perform manual step
File.Copy(AzureNames.CertificatesStorageLocation + @"\" + AzureNames.CertificateClient + ".crt", AzureNames.CertificatesStorageLocation + @"\" + AzureNames.CertificateClient + ".cer");
var userCommand = string.Format("openssl pkcs12 –export –in {0}.cer –inkey {0}.key –out {0}.pfx -passout pass:{1}", AzureNames.CertificateClient, AzureNames.CertificatePassword);
Console.WriteLine("Open command prompt, then run the following two statements as seperate commands(copy paste)");
Console.WriteLine("--------------------------");
Console.WriteLine("cd \"" + workingDirectory + "\"");
Console.WriteLine(userCommand);
Console.WriteLine("--------------------------");
Console.WriteLine("After you have successfully run the commands above:");
Console.WriteLine(" 1. Close the command prompt you just opened(not this one)");
Console.WriteLine(" 2. Press any key to continue");
Console.ReadKey();
Console.WriteLine();
Console.WriteLine("Continuing on...");
你所有的 C# 代码都在为 运行 "x509" 和朋友生成 shell 进程。
建议:由于您的环境是 MS Windows/MS Azure,请试试这个:
PS PKI:
New-SelfSignedCertificate
New-SelfSignedCertificate -DnsName "www.fabrikam.com",
"www.contoso.com" -CertStoreLocation "cert:\LocalMachine\My"
您可以指定任意数量的扩展名(通过 OID),包括:
The object identifiers of some common extensions are as follows:
Application Policy. 1.3.6.1.4.1.311.21.10
Application Policy Mappings. 1.3.6.1.4.1.311.21.11
Basic Constraints. 2.5.29.19
Certificate Policies. 2.5.29.32
Enhanced Key Usage. 2.5.29.37
Name Constraints. 2.5.29.30
Policy Mappings. 2.5.29.33
Subject Alternative Name. 2.5.29.17
另请参阅:
-
-
附录:
也可以直接在C#中生成自签名证书:
这完全支持证书扩展:
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
public class CertSelect
{
public static void Main()
{
try
{
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
for (int i = 0; i < collection.Count; i++)
{
foreach (X509Extension extension in collection[i].Extensions)
{
Console.WriteLine(extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")");
if (extension.Oid.FriendlyName == "Key Usage")
{
X509KeyUsageExtension ext = (X509KeyUsageExtension)extension;
Console.WriteLine(ext.KeyUsages);
}
if (extension.Oid.FriendlyName == "Basic Constraints")
{
X509BasicConstraintsExtension ext = (X509BasicConstraintsExtension)extension;
Console.WriteLine(ext.CertificateAuthority);
Console.WriteLine(ext.HasPathLengthConstraint);
Console.WriteLine(ext.PathLengthConstraint);
}
if (extension.Oid.FriendlyName == "Subject Key Identifier")
{
X509SubjectKeyIdentifierExtension ext = (X509SubjectKeyIdentifierExtension)extension;
Console.WriteLine(ext.SubjectKeyIdentifier);
}
if (extension.Oid.FriendlyName == "Enhanced Key Usage")
{
X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)extension;
OidCollection oids = ext.EnhancedKeyUsages;
foreach (Oid oid in oids)
{
Console.WriteLine(oid.FriendlyName + "(" + oid.Value + ")");
}
}
}
}
store.Close();
}
catch (CryptographicException)
{
Console.WriteLine("Information could not be written out for this certificate.");
}
}
}
现代 openSSL 使用必需的 .cnf 文件来实现原始教程中提到的功能:https://docs.microsoft.com/en-us/azure/application-gateway/self-signed-certificates
更改第二个openSSL进程
processInfo.Arguments = string.Format("req -config {1} -new -sha256 -key {0}.key -out {0}.csr -subj \"/C=US/ST=Denver/L=Denver/O=Enterprise Architecture/OU=Enterprise Architecture/CN=site.com/emailAddress=sample@sample.com\"", AzureNames.CertificateRoot, configFile);
添加所需的configFile.cnf
[要求]
req_extensions = v3_req
distinguished_name = dn
[dn]
[v3_req]
基本约束 = CA:TRUE
然后更改第三个openSSL进程
processInfo.Arguments = string.Format("x509 -req -sha256 -days 365 -extensions v3_ca -extfile {1} -in {0}.csr -signkey contoso.key -out {0}.crt", AzureNames.CertificateRoot, configCAFile);
添加所需的configFileCA.cnf
[v3_ca]
基本约束 = CA:TRUE
我正在尝试使用 azure rest 创建应用程序网关 api。我使用的是使用以下文档生成的自签名证书:
https://docs.microsoft.com/en-us/azure/application-gateway/self-signed-certificates
当我发送创建应用程序网关的请求时,出现以下错误:
不包含任何 CA 证书。 CA 证书包含主题类型为 CA 的基本约束扩展。
我曾尝试将根证书与客户端证书结合使用,但这似乎没有帮助。
该解决方案需要自动化,将 运行 来自 Windows 机器,这里是与文档相匹配的相关源代码 (C#):
Process process = null;
var processInfo = new ProcessStartInfo();
processInfo.FileName = AzureNames.OpenSSLBinaryLocation;
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
processInfo.WorkingDirectory = workingDirectory;
processInfo.Arguments = string.Format("ecparam -out {0}.key -name prime256v1 -genkey", AzureNames.CertificateRoot);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("req -new -sha256 -key {0}.key -out {0}.csr -subj \"/C=US/ST=Denver/L=Denver/O=Enterprise Architecture/OU=Enterprise Architecture/CN=site.com/emailAddress=sample@sample.com\"", AzureNames.CertificateRoot);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("x509 -req -sha256 -days 365 --extensions v3_ca -in {0}.csr -signkey contoso.key -out {0}.crt", AzureNames.CertificateRoot);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("ecparam -out {0}.key -name prime256v1 -genkey", AzureNames.CertificateClient);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("req -new -sha256 -key {0}.key -out {0}.csr -subj \"/C=US/ST=Denver/L=Denver/O=Enterprise Architecture/OU=Enterprise Architecture/CN=site.com/emailAddress=sample@sample.com\"", AzureNames.CertificateClient);
process = Process.Start(processInfo);
process.WaitForExit();
processInfo.Arguments = string.Format("x509 -req -in {0}.csr -CA {1}.crt -CAkey {1}.key -CAcreateserial -out {0}.crt -days 365 --extensions v3_ca -sha256", AzureNames.CertificateClient, AzureNames.CertificateRoot);
process = Process.Start(processInfo);
process.WaitForExit();
process.Close();
//combine root cert into client certificate
var rootContents = File.ReadAllText(AzureNames.CertificatesStorageLocation + @"\" + AzureNames.CertificateRoot + ".crt");
File.AppendAllText(AzureNames.CertificatesStorageLocation + @"\" + AzureNames.CertificateClient + ".crt", Environment.NewLine + rootContents);
//perform manual step
File.Copy(AzureNames.CertificatesStorageLocation + @"\" + AzureNames.CertificateClient + ".crt", AzureNames.CertificatesStorageLocation + @"\" + AzureNames.CertificateClient + ".cer");
var userCommand = string.Format("openssl pkcs12 –export –in {0}.cer –inkey {0}.key –out {0}.pfx -passout pass:{1}", AzureNames.CertificateClient, AzureNames.CertificatePassword);
Console.WriteLine("Open command prompt, then run the following two statements as seperate commands(copy paste)");
Console.WriteLine("--------------------------");
Console.WriteLine("cd \"" + workingDirectory + "\"");
Console.WriteLine(userCommand);
Console.WriteLine("--------------------------");
Console.WriteLine("After you have successfully run the commands above:");
Console.WriteLine(" 1. Close the command prompt you just opened(not this one)");
Console.WriteLine(" 2. Press any key to continue");
Console.ReadKey();
Console.WriteLine();
Console.WriteLine("Continuing on...");
你所有的 C# 代码都在为 运行 "x509" 和朋友生成 shell 进程。
建议:由于您的环境是 MS Windows/MS Azure,请试试这个:
PS PKI: New-SelfSignedCertificate
New-SelfSignedCertificate -DnsName "www.fabrikam.com", "www.contoso.com" -CertStoreLocation "cert:\LocalMachine\My"
您可以指定任意数量的扩展名(通过 OID),包括:
The object identifiers of some common extensions are as follows:
Application Policy. 1.3.6.1.4.1.311.21.10 Application Policy Mappings. 1.3.6.1.4.1.311.21.11 Basic Constraints. 2.5.29.19 Certificate Policies. 2.5.29.32 Enhanced Key Usage. 2.5.29.37 Name Constraints. 2.5.29.30 Policy Mappings. 2.5.29.33 Subject Alternative Name. 2.5.29.17
另请参阅:
附录:
也可以直接在C#中生成自签名证书:
这完全支持证书扩展:
using System; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; public class CertSelect { public static void Main() { try { X509Store store = new X509Store("MY", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; for (int i = 0; i < collection.Count; i++) { foreach (X509Extension extension in collection[i].Extensions) { Console.WriteLine(extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")"); if (extension.Oid.FriendlyName == "Key Usage") { X509KeyUsageExtension ext = (X509KeyUsageExtension)extension; Console.WriteLine(ext.KeyUsages); } if (extension.Oid.FriendlyName == "Basic Constraints") { X509BasicConstraintsExtension ext = (X509BasicConstraintsExtension)extension; Console.WriteLine(ext.CertificateAuthority); Console.WriteLine(ext.HasPathLengthConstraint); Console.WriteLine(ext.PathLengthConstraint); } if (extension.Oid.FriendlyName == "Subject Key Identifier") { X509SubjectKeyIdentifierExtension ext = (X509SubjectKeyIdentifierExtension)extension; Console.WriteLine(ext.SubjectKeyIdentifier); } if (extension.Oid.FriendlyName == "Enhanced Key Usage") { X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)extension; OidCollection oids = ext.EnhancedKeyUsages; foreach (Oid oid in oids) { Console.WriteLine(oid.FriendlyName + "(" + oid.Value + ")"); } } } } store.Close(); } catch (CryptographicException) { Console.WriteLine("Information could not be written out for this certificate."); } } }
现代 openSSL 使用必需的 .cnf 文件来实现原始教程中提到的功能:https://docs.microsoft.com/en-us/azure/application-gateway/self-signed-certificates
更改第二个openSSL进程
processInfo.Arguments = string.Format("req -config {1} -new -sha256 -key {0}.key -out {0}.csr -subj \"/C=US/ST=Denver/L=Denver/O=Enterprise Architecture/OU=Enterprise Architecture/CN=site.com/emailAddress=sample@sample.com\"", AzureNames.CertificateRoot, configFile);
添加所需的configFile.cnf
[要求]
req_extensions = v3_req
distinguished_name = dn
[dn]
[v3_req]
基本约束 = CA:TRUE
然后更改第三个openSSL进程
processInfo.Arguments = string.Format("x509 -req -sha256 -days 365 -extensions v3_ca -extfile {1} -in {0}.csr -signkey contoso.key -out {0}.crt", AzureNames.CertificateRoot, configCAFile);
添加所需的configFileCA.cnf
[v3_ca]
基本约束 = CA:TRUE