在我的应用程序中,我需要从数据库读取 Base64 字符串并创建 X509 证书。
该字符串是由另一段代码通过读取 PFX 文件创建的,并将其转换为字节数组,然后转换为 Base64 字符串 - 就像这样。
Convert.ToBase64String(File.ReadAllBytes(certificatePfxPath));
这是我编写的用于检索它的代码。
string certificatePassword = "my_password";
string cert64String = ""; // Read the base64 string from DB.
X509Certificate2 certificate = new X509Certificate2();
certificate.Import(Convert.FromBase64String(cert64String), certificatePassword,
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.UserKeySet);
代码在我的本地计算机上运行良好,但是当我将其部署到Azure应用程序服务时,代码抛出以下错误:
The system cannot find the file specified.
stack track
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)
我认为
X509KeyStorageFlags
参数一定是造成这个问题的原因,所以我尝试了第二种方法。
byte[] bytes = Convert.FromBase64String(cert64String);
X509Certificate2 certificate = new X509Certificate2(bytes);
但这也会引发同样的错误。我无法理解为什么它说关于文件路径,而我在这里不处理任何文件操作!
我在这里做错了什么?如何在部署环境中修复此问题?
经过一番分析,终于解决了这个问题。在这里发帖,以便将来可以帮助别人。
显然
certificate.Import
尝试写入主机的证书存储,这是错误的原因。
我更改了创建证书的方法,而不使用
Import
函数。以下代码对我有用。
X509Certificate2 certificate = new X509Certificate2(Convert.FromBase64String(cert64String),
certificatePassword,
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable);