3

我陷入了一个大问题。

我在 ASP.NET 中构建了一个 MVC WebAPI,它使用 google api(服务帐户)写入 google 电子表格。我可以很好地运行应用程序,也可以写入电子表格。但问题是当我将它托管在 Godaddy 的共享 Windows 服务器上时,它给了我一个错误。


[加密异常:

发生了内部错误。

]
System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 小时)+33 System.Security.Cryptography.X509Certificates.X509Utils。

_LoadCertFromFile(字符串文件名,IntPtr 密码,UInt32 dwFlags,布尔persistKeySet,SafeCertContextHandle& pCertCtx)

+0
System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(字符串文件名,对象密码,X509KeyStorageFlags keyStorageFlags)+218
System.Security.Cryptography.X509Certificates.X509Certificate.Import(字符串文件名,字符串密码,X509KeyStorageFlags keyStorageFlags)+33
系统。 Security.Cryptography.X509Certificates.X509Certificate2.Import(字符串文件名,字符串密码,X509KeyStorageFlags keyStorageFlags)+33
GAExampleMVC.GoogleAnalytics.GoogleAnalyticsService.GetStats() 在 d:\Aakash\Thermax\webapi\GAExampleMVC\GAExampleMVC\GoogleAnalytics\GoogleAnalytics.cs:50 GAExampleMVC.Controllers.HomeController.Index() 在 d:\Aakash\Thermax\webapi\GAExampleMVC \GAExampleMVC\Controllers\HomeController.cs:16 lambda_method(Closure, ControllerBase, Object[]) +62
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase 控制器, Object[] 参数) +14
System.Web.Mvc.ReflectedActionDescriptor。 Execute(ControllerContext controllerContext, IDictionary 2 参数) +27 System.Web.Mvc.<>c__DisplayClass15.b__12() +55 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func2 parameters) +211
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary

1 continuation) +253
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +21 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList
1 个过滤器,ActionDescriptor actionDescriptor,IDictionary`2 个参数)+189
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +324
System.Web.Mvc.Controller.ExecuteCore() +105


我只是不明白为什么它不能在 Godaddy 上运行,而相同的代码在 localhost 中运行良好。

我猜这与我的代码无法访问的某些证书​​存储有关。

任何人都可以帮助我了解确切的问题以及如何解决它。

4

1 回答 1

1

我知道这篇文章比较老,但我想我会根据我最近的经验提供一个答案,以防其他人遇到它。据我所知,实际问题是 GoDaddy 不允许更改共享主机上的应用程序池身份。要从根本上解决问题,必须为应用程序池身份设置“加载用户配置文件”设置。这允许加载 p12。但是,正如我所说,这不是共享托管平台的选择。所以,解决方法...

我对解决方案的灵感来自这篇文章。我没有玩Bouncy Castle的经验,也没有时间学习,所以这就是我想出的。

首先...获取 Google 使用开发者控制台提供的 p12 文件并将其转换为 pk8 私钥。我使用 OpenSSL 来做到这一点。

openssl pkcs12 -in file.p12 -nocerts -out key.pem
openssl pkcs8 -in key.pem -topk8 -out p8key.pem

其次,将生成的 pk8 密钥保存在您的应用程序 App_Data 文件夹中。

第三,使用 StreamReader 从 pk8 文件中读取密钥,并使用 .FromPrivateKey 而不是 .FromCertificate 初始化 ServiceAccountCredential。

Dim stReader As New System.IO.StreamReader _
(HostingEnvironment.ApplicationPhysicalPath & "[PathToPK8File].pk8")
        Dim aLine As String
        Dim keyfile As String
        While True
            aLine = stReader.ReadLine()
            If aLine Is Nothing Then
                keyfile = keyfile & vbCrLf
                Exit While
            Else
                keyfile = keyfile & aLine & " "
            End If
        End While

        Dim scopes As IList(Of String) = New List(Of String)()

        scopes.Add(CalendarService.Scope.CalendarReadonly)

        Dim credential As ServiceAccountCredential = New ServiceAccountCredential(
            New ServiceAccountCredential.Initializer(serviceEmail) With {
            .Scopes = scopes
            }.FromPrivateKey(keyfile)) // Use FromPrivateKey instead of FromCertificate

所有在生产服务器上正确加载。

于 2017-10-02T15:07:10.260 回答