我们有一个 C# 代码来从 keyvault 加载 x509 证书。 这段代码在我们的开发环境中运行没有任何问题。代码在这里
var signingCertificate = new X509Certificate2(buffer, certificatePassword, X509KeyStorageFlags.Exportable);
现在,部署到我们的暂存环境时,同一段代码会失败并出现以下错误。
我们检查了aks版本和底层windows版本。两者是相同的。 我们检查了部署 yaml。那里也没有变化。
我们能够更改 X509KeyStorageFlags 选项并使其正常工作。但想了解相同的代码如何以及为什么在较低的环境中工作,而不是在我们的临时部署中工作。
有关于如何解决这个奇怪问题的指导吗?
The system cannot find the file specified.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Utils.LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags, Boolean passwordProvided)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
为了在 aks 中运行的 .NET Core 应用程序中加载 X509 证书,并假设您已准备好 aks、acr 和 akv,您可以按照以下步骤操作。
仅供参考,此示例带有自签名证书。
更新您的program.cs文件,如下所示-
using System;
using System.Security.Cryptography.X509Certificates;
namespace LoadCertificateApp
{
class Program
{
static void Main(string[] args)
{
try
{
string certificatePassword = Environment.GetEnvironmentVariable("CERTIFICATE_PASSWORD");
byte[] buffer = Convert.FromBase64String(Environment.GetEnvironmentVariable("CERTIFICATE_BASE64"));
var signingCertificate = new X509Certificate2(buffer, certificatePassword, X509KeyStorageFlags.MachineKeySet);
Console.WriteLine("Certificate loaded successfully.");
}
catch (Exception ex)
{
Console.WriteLine($"Error loading certificate: {ex.Message}");
}
}
}
}
示例 Dockerfile
FROM mcr.microsoft.com/dotnet/runtime:5.0
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "LoadCertificateApp.dll"]
构建并推动-
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["LoadCertificateApp/LoadCertificateApp.csproj", "LoadCertificateApp/"]
RUN dotnet restore "LoadCertificateApp/LoadCertificateApp.csproj"
COPY . .
WORKDIR "/src/LoadCertificateApp"
RUN dotnet build "LoadCertificateApp.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "LoadCertificateApp.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "LoadCertificateApp.dll"]
为您的 k8s 部署创建一个秘密 -
az acr login --name arkoacr2
kubectl create secret docker-registry acr-secret --docker-server=arkoacr2.azurecr.io --docker-username=<username> --docker-password=<password> --docker-email=<email>
kubectl create secret generic cert-secret --from-literal=CERTIFICATE_PASSWORD=<cert-password> --from-literal=CERTIFICATE_BASE64=<base64-encoded-cert>
您可以使用以下命令获取上述命令中所需的 Base64 转换值 -
az keyvault secret download --vault-name arkokv1 --name MyCertificate --file MyCertificate.pfx
certutil -encode MyCertificate.pfx MyCertificate.base64
上面的命令会将您的证书转换为 Base64 文件
并相应地编辑您的特定应用程序部署以保存该 base64 证书。
apiVersion: apps/v1
kind: Deployment
metadata:
name: load-certificate-app
spec:
replicas: 1
selector:
matchLabels:
app: load-certificate-app
template:
metadata:
labels:
app: load-certificate-app
spec:
containers:
- name: load-certificate-app
image: arkoacr2.azurecr.io/load-certificate-app:latest
env:
- name: CERTIFICATE_PASSWORD
valueFrom:
secretKeyRef:
name: cert-secret
key: CERTIFICATE_PASSWORD
- name: CERTIFICATE_BASE64
valueFrom:
secretKeyRef:
name: cert-secret
key: CERTIFICATE_BASE64
imagePullSecrets:
- name: acr-secret