docker - Net Core Docker 容器 API。无法使用 System.Security.Cryptography.CryptographicException 处提供的密码读取证书数据
问题描述
使用 HTTPS 的 docker 容器中的 Web App Document Manager 和 Web API Document Uploader 之间的通信不起作用。我遵循以下关于如何在 docker 容器中使用 https 的建议。我假设我只需要在 API 中整理 SSL 证书。
https://github.com/dotnet/AspNetCore.Docs/issues/6199
有趣的一点是,Web App Document Manager 中的 https 可以正常工作,当我在浏览器中打开 Web App 时,https 很好。我很困扰。
我按照此链接https://github.com/dotnet/dotnet-docker/blob/main/samples/run-aspnetcore-https-development.md中的说明创建了 documentuploader.pfx 文件
但是我得到了响应“一个有效的 HTTPS 证书已经存在。”,因此我导出了一个已经存在的名为 localhost.pfx 的证书,但它没有用。我检查了密码,但它是正确的。
当我使用 docker compose 运行容器时,出现以下错误。
System.Security.Cryptography.CryptographicException
HResult=0x80070056
Message=The certificate data cannot be read with the provided password, the password may be incorrect.
Source=System.Security.Cryptography.X509Certificates
StackTrace:
at Internal.Cryptography.Pal.UnixPkcs12Reader.Decrypt(SafePasswordHandle password)
at Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs12(OpenSslPkcs12Reader pfx, SafePasswordHandle password, Boolean single, ICertificatePal& readPal, List`1& readCerts)
at Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs12(ReadOnlySpan`1 rawData, SafePasswordHandle password, Boolean single, ICertificatePal& readPal, List`1& readCerts, Exception& openSslException)
at Internal.Cryptography.Pal.OpenSslX509CertificateReader.FromFile(String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Certificates.CertificateConfigLoader.LoadCertificate(CertificateConfig certInfo, String endpointName)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadDefaultCert()
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Reload()
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<BindAsync>d__32.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.
...
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
at DocumentUploader.Program.Main(String[] args)
This exception was originally thrown at this call stack:
Internal.Cryptography.Pal.UnixPkcs12Reader.VerifyAndDecrypt(System.ReadOnlySpan<char>, System.ReadOnlyMemory<byte>)
Internal.Cryptography.Pal.UnixPkcs12Reader.Decrypt(Microsoft.Win32.SafeHandles.SafePasswordHandle)
Inner Exception 1:
CryptographicException: The certificate data cannot be read with the provided password, the password may be incorrect.
我的码头工人撰写是
version: '3.5'
services:
documentmanager:
image: ${DOCKER_REGISTRY-}documentmanager
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://localhost;http://localhost
- ASPNETCORE_HTTPS_PORT=44349
# Do not create development certificate in an environment that will be distributed.
#- DOTNET_GENERATE_ASPNET_CERTIFICATE=false
networks:
- doc_manager
ports:
- "51218:80"
- "44349:443"
volumes:
- ${APPDATA}/Microsoft/UserSecrets/:/root/.microsoft/usersecrets
- ${APPDATA}/ASP.NET/Https/:/root/.aspnet/https/
build:
context: .
dockerfile: Document Manager/Dockerfile
documentuploader:
image: ${DOCKER_REGISTRY-}documentuploader
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://localhost;http://localhost
- ASPNETCORE_HTTPS_PORT=44335
# Do not create development certificate in an environment that will be distributed.
#- DOTNET_GENERATE_ASPNET_CERTIFICATE=false
networks:
- doc_manager
ports:
- "51217:80"
- "44335:443"
volumes:
- ${APPDATA}/Microsoft/UserSecrets/:/root/.microsoft/usersecrets
- ${APPDATA}/ASP.NET/Https/:/root/.aspnet/https/
build:
context: .
dockerfile: DocumentUploader/Dockerfile
networks:
doc_manager:
driver: bridge
我在 documentuploader api 项目中的秘密文件是
"Kestrel": {
"Certificates": {
"Default": {
"Path": "/root/.aspnet/https/documentuploader.pfx",
"Password": "PASSWORD IS HERE"
}
}
}
我的 DocumentUploader.pfx 被复制到容器中的 /root/.aspnet/https 文件夹中。
当我使用 openssl 程序检查密码是否正确时,显示的内容是
MAC: sha1, Iteration 2000
MAC length: 20, salt length: 20
PKCS7 Data
Shrouded Keybag: <key bag here>, Iteration 2000
PKCS7 Encrypted data: <PKCS7 here>, Iteration 2000
Certificate bag
Bag Attributes
localKeyID: 01 00 00 00
friendlyName: IIS Express Development Certificate
subject=CN = localhost
issuer=CN = localhost
---BEGIN CERIFICATE---
有什么帮助吗?
解决方案
如果您已按照说明https://github.com/dotnet/dotnet-docker/blob/main/samples/run-aspnetcore-https-development.md,则以下 docker compose 适用于我的情况:
版本:'3.5'
服务:
dockerex4:
image: dockerex4image container_name: DockerEx4 environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://+:80;https://+:443 # If you instead choose to copy cert in Dockerfile, you don't need volumes #- ASPNETCORE_Kestrel__Certificates__Default__Path=/app/DockerEx4.pfx #- ASPNETCORE_Kestrel__Certificates__Default__Password=crypticpassword ports: - 9000:80 - 9001:443 volumes: - C:\Users\rwilliams\AppData\Roaming\Microsoft\UserSecrets:/root/.microsoft/usersecrets:ro - C:\Users\rwilliams\source\repos\slnDragAndDrop\Artifacts\certs:/root/.aspnet/https:ro
注意:这些文档和我的 docker-compose 中的一个差异是:
dotnet user-secrets -p aspnetapp\aspnetapp.csproj 设置“Kestrel:Certificates:Development:Password”“crypticpassword”
暗示在你的秘密中,“默认”应该是“发展”。很抱歉代码中的空行。您不应该同时需要卷和 ASPNETCORE_Kestrel 环境变量。在我的方法中也是非标准的,我选择在我的解决方案根目录下指定一个卷证书目录。
编辑:另外,你很可能有错误的证书。友好名称应为“ASP.NET Core HTTPS 开发证书”而不是“IIS 开发...”
推荐阅读
- c++ - 在数组中创建位置层次结构
- extjs - ext.net 1 - 如何根据后面代码中的行数据构造div元素ID
- android - 导航架构不使用单个 Activity
- php - 将文件放在子文件夹中到谷歌驱动器使用 laravel
- vb.net - msvsmon.exe 未在 Windows IOT 上运行
- asp.net-mvc - 如何使用状态码返回 EmptyResult
- spring-mvc - 知道如何实现只带来您搜索过的值的视图吗?
- amazon-web-services - 步骤函数中的 aws 胶水作业依赖性
- python - 为什么当 N=1 时我得到一个空列表而不是 [0]
- python - Django模型继承奇怪或预期的行为?