使用 MySQL TLS 的经典 ASP 中的 CryptographicException
CryptographicException in Classic ASP with MySQL TLS
当我尝试调用 classic ASP 页面中的 COM Visible c# class 时,我遇到了这个问题,该页面试图执行一个 MySQL 查询数据库。(此处 MySQL 在 TLS 上)。
在我的案例中,classic asp 页面之一,我们创建了 SomeUser class 的实例,然后调用 SetId 方法来尝试创建 MySQL 连接并失败并显示此堆栈跟踪 。为了完全清楚起见,这里 SomeUser class 是 COMVisible。
经典ASP代码段
dim dummy: set dummy= new SomeUser
dim dummyObj: set dummyObj= dummy.obj
dummyObj.SetId(ID)
异常
System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) at System.Security.Cryptography.X509Certificates.X509Utils.LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password) at MySql.Data.MySqlClient.NativeDriver.GetClientCertificates()
at MySql.Data.MySqlClient.NativeDriver.StartSSL() at MySql.Data.MySqlClient.NativeDriver.Open() at MySql.Data.MySqlClient.Driver.Open()
at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings) at MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection() at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver() at MySql.Data.MySqlClient.MySqlPool.GetConnection()
at MySql.Data.MySqlClient.MySqlConnection.Open() at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable) at Some.Other.Namespace.Execute(MySqlConnection connection, String sql, DataTable table, DataParameter[] dataParameters) at Some.Other.Namespace.Execute(MySqlConnection connection, String sql, DataParameter[] dataParameters) at Some.Other.Namespace.Execute(String sql, DataParameter[] dataParameters)
at SomeNamespace.SomeDc.GetData(UInt32 Id) at
SomeNamespace.User.GetData(UInt32 ID) at SomeNameSpace.SomeUser.SetId(Int32 Id)
Similar question on Stack Overflow 就此.
在我的例子中,此解决方案(将加载用户配置文件设置为 true)仅适用于 ASPX 页,但在本例中无效。
还有一点我想强调 w3wp.exe 是 运行 in Default App Pool with ApplicationPoolIdentity.
到目前为止我已经尝试了很多东西但没有成功。方向正确的任何一点都会有很大帮助。
到目前为止我已经尝试过的事情。
- 将所有应用程序池的加载用户配置文件设置为 true。
- 正在将应用程序池标识更改为网络服务、本地系统
和 IIS 中的其他人。
- 正在将应用程序池标识更改为
自定义帐户(我使用管理员帐户来尝试)
我对ASP一无所知,所以我不明白你试过什么。
但是,异常日志似乎告诉了哪里出了问题。 ASP / COM 应用程序在连接到 MySQL 服务器时试图加载 客户端 证书,但找不到相应的文件。这可能是由于权限问题,也可能只是因为该文件不存在。
请注意,这是一个 not-so-common 问题,可能会妨碍您快速找到解决方案。证书问题通常是由于 服务器 证书不受信任、吊销或过时。但在这种情况下,COM 部分试图加载 client 证书,以便它可以证明 its 身份 to服务器。
解决问题的方法视情况而定:
如果您控制着 MySQL 服务器,您可以将其配置为不请求客户端证书。然后 COM 代码不再需要加载客户端证书,您可以相应地更改 COM 对象的行为。但是,在服务器上关闭客户端身份验证可能不安全。
您似乎控制了 COM 代码,因此您可以重新访问它并查看它尝试加载 MySQL 客户端证书的位置。检查它试图加载哪个文件,并检查文件系统上是否有该文件。如果不存在,并且无法在没有客户端证书的情况下工作,则您必须生成客户端证书。
不过,我不知道 COM 对象是如何工作的。即使您没有找到它试图显式加载客户端证书的地方,它也可能会评估一些 MySQL 客户端配置文件,告诉它在连接到服务器时使用(特定)客户端证书。此类文件的名称可能类似于 mysql.ini
、my.ini
、my.cnf
等。
澄清:以上段落是关于 MySQL TLS 连接的 MySQL 客户端 证书。这与网络服务器证书无关。
如果需要MySQL客户端认证,请一步步测试:
- 生成适当的 MySQL 客户端证书。
- 将该客户端证书与私钥一起放到运行 COM 应用程序的计算机上。
- 登录那台机器并在那里安装本机MySQL客户端(它可用于Windows)。
- 在那台机器上,尝试使用客户端身份验证与您的 MySQL 服务器建立加密连接,使用本机 MySQL 客户端 并使用您的客户端证书.
如果这不起作用,它可能无法在您的 COM 对象中起作用,因此您需要先解决这个问题。
- 在最后一步中,再次尝试 ASP 应用程序/COM 对象。确保它有足够的权限读取证书和私钥,并且两者都存在于预期的位置。
如果与本机客户端连接成功,但 COM 对象仍然无法连接,我可能对如何调试这种情况有了额外的想法。在那种情况下,只需发表评论即可;我最终会修改这个答案。
当我尝试调用 classic ASP 页面中的 COM Visible c# class 时,我遇到了这个问题,该页面试图执行一个 MySQL 查询数据库。(此处 MySQL 在 TLS 上)。
在我的案例中,classic asp 页面之一,我们创建了 SomeUser class 的实例,然后调用 SetId 方法来尝试创建 MySQL 连接并失败并显示此堆栈跟踪 。为了完全清楚起见,这里 SomeUser class 是 COMVisible。
经典ASP代码段
dim dummy: set dummy= new SomeUser
dim dummyObj: set dummyObj= dummy.obj
dummyObj.SetId(ID)
异常
System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) at System.Security.Cryptography.X509Certificates.X509Utils.LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password) at MySql.Data.MySqlClient.NativeDriver.GetClientCertificates()
at MySql.Data.MySqlClient.NativeDriver.StartSSL() at MySql.Data.MySqlClient.NativeDriver.Open() at MySql.Data.MySqlClient.Driver.Open()
at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings) at MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection() at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver() at MySql.Data.MySqlClient.MySqlPool.GetConnection()
at MySql.Data.MySqlClient.MySqlConnection.Open() at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable) at Some.Other.Namespace.Execute(MySqlConnection connection, String sql, DataTable table, DataParameter[] dataParameters) at Some.Other.Namespace.Execute(MySqlConnection connection, String sql, DataParameter[] dataParameters) at Some.Other.Namespace.Execute(String sql, DataParameter[] dataParameters)
at SomeNamespace.SomeDc.GetData(UInt32 Id) at
SomeNamespace.User.GetData(UInt32 ID) at SomeNameSpace.SomeUser.SetId(Int32 Id)
Similar question on Stack Overflow 就此.
在我的例子中,此解决方案(将加载用户配置文件设置为 true)仅适用于 ASPX 页,但在本例中无效。
还有一点我想强调 w3wp.exe 是 运行 in Default App Pool with ApplicationPoolIdentity.
到目前为止我已经尝试了很多东西但没有成功。方向正确的任何一点都会有很大帮助。
到目前为止我已经尝试过的事情。
- 将所有应用程序池的加载用户配置文件设置为 true。
- 正在将应用程序池标识更改为网络服务、本地系统 和 IIS 中的其他人。
- 正在将应用程序池标识更改为 自定义帐户(我使用管理员帐户来尝试)
我对ASP一无所知,所以我不明白你试过什么。
但是,异常日志似乎告诉了哪里出了问题。 ASP / COM 应用程序在连接到 MySQL 服务器时试图加载 客户端 证书,但找不到相应的文件。这可能是由于权限问题,也可能只是因为该文件不存在。
请注意,这是一个 not-so-common 问题,可能会妨碍您快速找到解决方案。证书问题通常是由于 服务器 证书不受信任、吊销或过时。但在这种情况下,COM 部分试图加载 client 证书,以便它可以证明 its 身份 to服务器。
解决问题的方法视情况而定:
如果您控制着 MySQL 服务器,您可以将其配置为不请求客户端证书。然后 COM 代码不再需要加载客户端证书,您可以相应地更改 COM 对象的行为。但是,在服务器上关闭客户端身份验证可能不安全。
您似乎控制了 COM 代码,因此您可以重新访问它并查看它尝试加载 MySQL 客户端证书的位置。检查它试图加载哪个文件,并检查文件系统上是否有该文件。如果不存在,并且无法在没有客户端证书的情况下工作,则您必须生成客户端证书。
不过,我不知道 COM 对象是如何工作的。即使您没有找到它试图显式加载客户端证书的地方,它也可能会评估一些 MySQL 客户端配置文件,告诉它在连接到服务器时使用(特定)客户端证书。此类文件的名称可能类似于mysql.ini
、my.ini
、my.cnf
等。
澄清:以上段落是关于 MySQL TLS 连接的 MySQL 客户端 证书。这与网络服务器证书无关。
如果需要MySQL客户端认证,请一步步测试:
- 生成适当的 MySQL 客户端证书。
- 将该客户端证书与私钥一起放到运行 COM 应用程序的计算机上。
- 登录那台机器并在那里安装本机MySQL客户端(它可用于Windows)。
- 在那台机器上,尝试使用客户端身份验证与您的 MySQL 服务器建立加密连接,使用本机 MySQL 客户端 并使用您的客户端证书.
如果这不起作用,它可能无法在您的 COM 对象中起作用,因此您需要先解决这个问题。 - 在最后一步中,再次尝试 ASP 应用程序/COM 对象。确保它有足够的权限读取证书和私钥,并且两者都存在于预期的位置。
如果与本机客户端连接成功,但 COM 对象仍然无法连接,我可能对如何调试这种情况有了额外的想法。在那种情况下,只需发表评论即可;我最终会修改这个答案。