在 android .net 6.0 应用程序中读取 X509 证书

Read X509 certificate in android .net 6.0 application

我正在尝试将我的 .net android 应用程序从“android xamarin 应用程序”迁移到 .net 6.0。 我终于完成了构建,现在每次我从字节数组读取 X509 证书时它都会掉落:

return new X509Certificate(bytes);

我确定证书是有效的,因为在迁移之前没有问题。 异常堆栈跟踪是:

System.PlatformNotSupportedException: Cryptography_AlgorithmNotSupported, RC2
at System.Security.Cryptography.PasswordBasedEncryption.CreateRC2()
at System.Security.Cryptography.PasswordBasedEncryption.Decrypt(AlgorithmIdentifierAsn& algorithmIdentifier, ReadOnlySpan`1 password, ReadOnlySpan`1 passwordBytes, ReadOnlySpan`1 encryptedData, Span`1 destination)
Internal.Cryptography.Pal.UnixPkcs12Reader.DecryptAndProcessSafeContents(ReadOnlySpan`1 password, CertBagAsn[]& certBags, AttributeAsn[][]& certBagAttrs, Int32& certBagIdx, SafeBagAsn[]& keyBags, Int32& keyBagIdx)
at Internal.Cryptography.Pal.UnixPkcs12Reader.Decrypt(ReadOnlySpan`1 password, ReadOnlyMemory`1 authSafeContents)
at Internal.Cryptography.Pal.UnixPkcs12Reader.VerifyAndDecrypt(ReadOnlySpan`1 password, ReadOnlyMemory`1 authSafeContents)
at Internal.Cryptography.Pal.UnixPkcs12Reader.Decrypt(SafePasswordHandle password, Boolean ephemeralSpecified)
Exception_EndOfInnerExceptionStack
at Internal.Cryptography.Pal.UnixPkcs12Reader.Decrypt(SafePasswordHandle password, Boolean ephemeralSpecified)
at Internal.Cryptography.Pal.AndroidCertificatePal.ReadPkcs12(ReadOnlySpan`1 rawData, SafePasswordHandle password, Boolean ephemeralSpecified)
at Internal.Cryptography.Pal.AndroidCertificatePal.FromBlob(ReadOnlySpan`1 rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at Internal.Cryptography.Pal.CertificatePal.FromBlob(ReadOnlySpan`1 rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] data)
...

我试图找到一些关于它的信息,但发现我无法创建“RC2” 在 runtime/src/libraries/Common/src/Internal/Cryptography/Helpers.cs 文件中:

#if NET5_0_OR_GREATER
        [UnsupportedOSPlatformGuard("android")]
        [UnsupportedOSPlatformGuard("browser")]
        public static bool IsRC2Supported => !OperatingSystem.IsAndroid();
#else
        public static bool IsRC2Supported => true;
#endif

所以问题是:
有谁知道为什么这个代码不受支持?
我能以某种方式在我的 .net 6.0 android 应用程序中使用 x509 证书吗?

Does anyone know why is this code unsupported?

.NET 6 for Android 使用 Android 内置加密提供程序,但不包括 RC2。

now it falls each time I start it on reading X509 certificate from byte array

从技术上讲,您的字节不是证书。它们是 PFX,并且 PFX 中的证书使用 40 位 RC2 加密(一种算法非常弱,它也可能是 ROT13,但这是 1990 年代美国密码法规的平衡行为......然后传统)。

Could I somehow use x509 certificate in my .net 6.0 android app?

如果您在 .NET 6 中将 Windows、Linux 或 macOS 的 PFX 加载为可导出,然后将其重新导出为新的 PFX,它应该可以工作在 Android 上;因为所有现代堆栈都应该使用 3DES 而不是 RC2-40(他们仍在使用 3DES 而不是 AES,因为并非所有市场上的 OS 版本都将 AES 连接到他们的 PFX 阅读器)。

X509Certificate2Collection coll = new X509Certificate2Collection();
coll.Import(bytes, pwd, X509KeyStorageFlags.Exportable);
byte[] newPfx = coll.Export(X509ContentType.Pfx, pwd);

或者,如果您使用 OpenSSL 的命令行实用程序来构建您的 PFX,请将 -certpbe 3DES 添加到您的命令行(例如 openssl pkcs12 -export -in cert.cer -inkey cert.key -certpbe 3DES -out cert.pfx)。