我已經看到了這個問題,間歇性爲好。在我的情況下,事實證明,獲得一個根證書的網絡連接有時會超時。然後在未來的請求,它會再次工作。
我最終編寫了一個自定義回調函數,讓我感興趣的特定證書儘管出現錯誤,但不影響其他證書的驗證。以下是我的代碼。正如你可能知道的那樣,我試圖打擊Android Cloud-to-Device Messaging終端,並嘗試解決Google使用的通配證書問題,但這應該是可以推廣的。這也有我用來診斷特定錯誤的所有記錄。即使您不想強制驗證證書,日誌代碼也可以幫助您決定如何繼續。
private static readonly Uri PUSH_URI = new Uri("https://android.apis.google.com/c2dm/send", UriKind.Absolute);
/**
//The following function needs to be wired up in code somewhere else, like this:
ServicePointManager.ServerCertificateValidationCallback += ValidateDodgyGoogleCertificate;
**/
/// <summary>
/// Validates the SSL server certificate. Note this is process-wide code.
/// Wrote a custom one because the certificate used for Google's push endpoint is not for the correct domain. Go Google.
/// </summary>
/// <param name="sender">either a host name string, or an object derived from WebRequest</param>
/// <param name="cert">The certificate used to authenticate the remote party.</param>
/// <param name="chain">The chain of certificate authorities associated with the remote certificate.</param>
/// <param name="sslPolicyErrors">One or more errors associated with the remote certificate.</param>
/// <returns>
/// Returns a boolean value that determines whether the specified
/// certificate is accepted for authentication; true to accept or false to
/// reject.
/// </returns>
private static bool ValidateDodgyGoogleCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
// Good certificate.
return true;
}
string hostName = sender as string;
if (hostName == null)
{
WebRequest senderRequest = sender as WebRequest;
if (senderRequest != null)
{
hostName = senderRequest.RequestUri.Host;
}
}
//We want to get past the Google name mismatch, but not allow any other errors
if (sslPolicyErrors != SslPolicyErrors.RemoteCertificateNameMismatch)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Rejecting remote server SSL certificate from host \"{0}\" issued to Subject \"{1}\" due to errors: {2}", hostName, cert.Subject, sslPolicyErrors);
if ((sslPolicyErrors | SslPolicyErrors.RemoteCertificateChainErrors) != SslPolicyErrors.None)
{
sb.AppendLine();
sb.AppendLine("Chain status errors:");
foreach (var chainStatusItem in chain.ChainStatus)
{
sb.AppendFormat("Chain Item Status: {0} StatusInfo: {1}", chainStatusItem.Status, chainStatusItem.StatusInformation);
sb.AppendLine();
}
}
log.Info(sb.ToString());
return false;
}
if (PUSH_URI.Host.Equals(hostName, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
log.Info("Rejecting remote server SSL certificate from host \"{0}\" issued to Subject \"{1}\" due to errors: {2}", hostName, cert.Subject, sslPolicyErrors);
return false;
}
不幸的是,我無法控制它。當我在本地測試(不使用Azure模擬器)時,它連接並正常工作。這似乎是Azure無法找到正確證書的權限問題。我確實嘗試了你的建議,並且非常感謝。然而,這更像是一種解決方法。 – 2012-04-05 16:25:34