这就是我要实现的目标。我们正在Kubernetes上开发一个微服务应用程序。微服务之一是IdentityServer实例。最初,我想在Docker上本地测试该解决方案以确保其有效。为此,我想将证书粘贴到appsettings.json。最终,该值将被Kubernetes机密替换。在我的启动课程中,这是我尝试加载证书的方式:
services.AddIdentityServer()
.AddSigningCredential(GetIdentityServerCertificate())
.AddConfigurationStore(...
private X509Certificate2 GetIdentityServerCertificate()
{
var clientSecret = Configuration["Certificate"];
var pfxBytes = Convert.FromBase64String(clientSecret);
var certificate = new X509Certificate2(pfxBytes);
return certificate;
}
证书是由我使用openssl生成的:
openssl req –newkey rsa:2048 –nodes –keyout XXXXX.key –x509 –days 365 –out XXXXX.cer
openssl pkcs12 –export –in XXXX.cer –inkey XXXX.key –out XXXX.pfx
然后我通过使用以下方式获得证书:
openssl pkcs12 -in XXXX.pfx -info -nokeys
-----BEGIN CERTIFICATE-----
i take this content and paste into appconfig.json
-----END CERTIFICATE-----
当我调试它时,结果是: System.InvalidOperationException:'X509证书没有私钥。'
答案 0 :(得分:1)
以下是在.net core中工作的示例:
使用openssl工具。打开终端并输入以下命令:
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
这将导致创建2个文件。
在.NET Core应用程序中实际使用RSA密钥之前,还有另外一件事。我们需要将它们转换为XML。使用“ RSA PEM到XML转换器”。 可以在这里完成:Online rsa key converter 将XML复制到private-rsa-key.xml和public-rsa-key.xml文件之前,请使用以下格式设置它们:XML Formatter
只有负责生成令牌的服务才需要私钥。不得在该项目外部共享。
Startup.cs:
public class Startup
{
public IConfiguration Configuration { get; }
private SigningCredentials _signingCredentials;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
// other code
services
.AddIdentityServer()
.AddSigningCredential(_signingCredentials)
.AddInMemoryApiResources(_identityConfig.GetApiResources())
.AddInMemoryClients(_identityConfig.GetClients());
// other code
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc();
app.UseIdentityServer();
}
private void InitializeRsaKey()
{
try
{
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(2048);
var rsaParametersPrivate = RSAExtensions.RSAParametersFromXmlFile(Configuration.GetSection("JwtSettings:rsaPrivateKeyXml").Value);
rsaProvider.ImportParameters(rsaParametersPrivate);
var securityKey = new RsaSecurityKey(rsaProvider);
_signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256);
}
catch(Exception ex)
{
throw new Exception("Identity Server RSA Key initialization failed. " + ex.ToString());
}
}
}
RSAExtensions类:
public static class RSAExtensions
{
/// <summary>
/// Gets RSA Parameters from XML file.
/// </summary>
/// <param name="xmlFilePath">The XML file path.</param>
/// <returns>RSAParameters.</returns>
/// <exception cref="Exception">Invalid XML RSA key.</exception>
public static RSAParameters RSAParametersFromXmlFile(string xmlFilePath)
{
RSAParameters parameters = new RSAParameters();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(File.ReadAllText(xmlFilePath));
if (xmlDoc.DocumentElement.Name.Equals("RSAKeyValue"))
{
foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
{
switch (node.Name)
{
case "Modulus": parameters.Modulus = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "Exponent": parameters.Exponent = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "P": parameters.P = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "Q": parameters.Q = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "DP": parameters.DP = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "DQ": parameters.DQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "InverseQ": parameters.InverseQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
case "D": parameters.D = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break;
}
}
}
else
{
throw new Exception("Invalid XML RSA key.");
}
return parameters;
}
}
在appsettings.json中添加以下内容:
"JwtSettings": {
"rsaPrivateKeyXml": "RSAKeys/private-rsa-key.xml",
},
我不知道您是否可以将原始XML存储在appsettings.json中。如果不是,您可以编写一个辅助方法,将pem转换为xml并将原始pem内容存储在配置变量中。
我在GitHub上找到了一个示例项目,可能会帮助您进行转换:Rsa-Dotnet-Core