仅在 Docker 容器中:ec_key_simple_check_key:invalid 私钥
Only in Docker container: ec_key_simple_check_key:invalid private key
我使用 BouncyCastle.Crypto 1.8.5.0 创建一个 SecurityKey 以针对 Apple 的 APNS HTTP/2 端点进行身份验证。在 MacOS Mojave 上调试时它工作得很好,但是当我在 Docker 容器中部署时,出现以下异常:
Interop+Crypto+OpenSslCryptographicException: error:1010207B:elliptic curve routines:ec_key_simple_check_key:invalid private key
at System.Security.Cryptography.ECOpenSsl.ImportParameters(ECParameters parameters)
at System.Security.Cryptography.ECDsa.Create(ECParameters parameters)
阅读 this 后,我尝试通过设置环境变量 CLR_OPENSSL_VERSION_OVERRIDE=1.1 并确保在 Docker 文件中安装了最新的 openssl 来强制使用 OpenSSL 1.1,但没有修复.
读取私钥文件并初始化SecurityKey的代码:
using (var reader = System.IO.File.OpenText (PathToApnsKeyFile)) {
var ecPrivateKeyParameters = (ECPrivateKeyParameters)new PemReader (reader).ReadObject ();
var x = ecPrivateKeyParameters.Parameters.G.AffineXCoord.GetEncoded ();
var y = ecPrivateKeyParameters.Parameters.G.AffineYCoord.GetEncoded ();
var d = ecPrivateKeyParameters.D.ToByteArrayUnsigned ();
// Convert the BouncyCastle key to a Native Key.
var msEcp = new ECParameters { Curve = ECCurve.NamedCurves.nistP256, Q = { X = x, Y = y }, D = d };
jwtPrivateKey = new ECDsaSecurityKey (ECDsa.Create (msEcp));
}
Docker文件:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic AS build-env
WORKDIR /app
# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out -r linux-x64
# build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic AS runtime
RUN apt-get update && apt-get -y install openssl
WORKDIR /app
COPY --from=build-env /app/out ./
ENTRYPOINT ["dotnet", "helloapple.dll"]
更新
我的 MacOS 似乎正在使用 LibreSSL 2.6.5。 apt-get拉取的openssl版本为1.1.1-1ubuntu2.1~18.04.7.
我终于找到了答案。原来问题出在曲线参数的实现上,这在平台之间是不同的。上面的代码适用于 Windows 和 Mac,但显然不适用于 Linux。正确的计算是:
var q = ecPrivateKeyParameters.Parameters.G.Multiply (ecPrivateKeyParameters.D).Normalize ();
var x = q.AffineXCoord.GetEncoded ();
var y = q.AffineYCoord.GetEncoded ();
var d = ecPrivateKeyParameters.D.ToByteArrayUnsigned ();
// Convert the BouncyCastle key to a Native Key.
var msEcp = new ECParameters { Curve = ECCurve.NamedCurves.nistP256, Q = { X = x, Y = y }, D = d };
在 github 的以下评论中找到了解决方案:
https://github.com/dotnet/core/issues/2037#issuecomment-436340605
我使用 BouncyCastle.Crypto 1.8.5.0 创建一个 SecurityKey 以针对 Apple 的 APNS HTTP/2 端点进行身份验证。在 MacOS Mojave 上调试时它工作得很好,但是当我在 Docker 容器中部署时,出现以下异常:
Interop+Crypto+OpenSslCryptographicException: error:1010207B:elliptic curve routines:ec_key_simple_check_key:invalid private key
at System.Security.Cryptography.ECOpenSsl.ImportParameters(ECParameters parameters)
at System.Security.Cryptography.ECDsa.Create(ECParameters parameters)
阅读 this 后,我尝试通过设置环境变量 CLR_OPENSSL_VERSION_OVERRIDE=1.1 并确保在 Docker 文件中安装了最新的 openssl 来强制使用 OpenSSL 1.1,但没有修复.
读取私钥文件并初始化SecurityKey的代码:
using (var reader = System.IO.File.OpenText (PathToApnsKeyFile)) {
var ecPrivateKeyParameters = (ECPrivateKeyParameters)new PemReader (reader).ReadObject ();
var x = ecPrivateKeyParameters.Parameters.G.AffineXCoord.GetEncoded ();
var y = ecPrivateKeyParameters.Parameters.G.AffineYCoord.GetEncoded ();
var d = ecPrivateKeyParameters.D.ToByteArrayUnsigned ();
// Convert the BouncyCastle key to a Native Key.
var msEcp = new ECParameters { Curve = ECCurve.NamedCurves.nistP256, Q = { X = x, Y = y }, D = d };
jwtPrivateKey = new ECDsaSecurityKey (ECDsa.Create (msEcp));
}
Docker文件:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic AS build-env
WORKDIR /app
# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out -r linux-x64
# build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic AS runtime
RUN apt-get update && apt-get -y install openssl
WORKDIR /app
COPY --from=build-env /app/out ./
ENTRYPOINT ["dotnet", "helloapple.dll"]
更新
我的 MacOS 似乎正在使用 LibreSSL 2.6.5。 apt-get拉取的openssl版本为1.1.1-1ubuntu2.1~18.04.7.
我终于找到了答案。原来问题出在曲线参数的实现上,这在平台之间是不同的。上面的代码适用于 Windows 和 Mac,但显然不适用于 Linux。正确的计算是:
var q = ecPrivateKeyParameters.Parameters.G.Multiply (ecPrivateKeyParameters.D).Normalize ();
var x = q.AffineXCoord.GetEncoded ();
var y = q.AffineYCoord.GetEncoded ();
var d = ecPrivateKeyParameters.D.ToByteArrayUnsigned ();
// Convert the BouncyCastle key to a Native Key.
var msEcp = new ECParameters { Curve = ECCurve.NamedCurves.nistP256, Q = { X = x, Y = y }, D = d };
在 github 的以下评论中找到了解决方案:
https://github.com/dotnet/core/issues/2037#issuecomment-436340605