我目前正在构建一个支持HTTPS的C#中间代理服务器,我以一种有点讨厌的方式重新授权证书,但这是我对这个项目所需要的。
我正在使用BouncyCastle生成CA证书和HTTP适合的证书,我注意到SslStream
将不接受任何非MD5WithRSA
的证书签名算法,这意味着Google Chrome和Firefox只会拒绝打开网页,因为它的签名算法需要SHA1WithRSA
。
我用来生成和验证SSL流的完整代码块位于http://cdn.afterlifelochie.rocket-it.com.au/temp/proxy-https.c-sharp.txt,但这是返回错误的简短代码段。
sslStream.AuthenticateAsServer(
cert, false, SslProtocols.Default | SslProtocols.Tls |
SslProtocols.Ssl3 | SslProtocols.Ssl2, false);
其中cert
是链中CA的签名HTTPS证书,包括CA私钥和HTTPS私钥,返回此错误:
SSL-Exception: A call to SSPI failed, see inner exception.
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken messag
e, AsyncProtocolRequest asyncRequest, Exception exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToke
n message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, A
syncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 coun
t, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes
, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocol
Request asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToke
n message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, A
syncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 coun
t, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes
, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocol
Request asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToke
n message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, A
syncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 coun
t, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes
, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocol
Request asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToke
n message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, A
syncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 coun
t, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes
, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocol
Request asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byt
e[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyRes
ult)
at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverC
ertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols,
Boolean checkCertificateRevocation)
at HTTPProxyServer.ProxyServer.DoHttpProcessing(TcpClient client) in C:\Users
\AfterLifeLochie\Desktop\C#Proxy\ProxyServer.cs:line 324
SSL-Inner-Exception: The specified data could not be decrypted
但是,如果我将来自SetSignatureAlgorithm(String Method)
的第76行的参数MD5withRSA
更改为SHA1WithRSA
,一切正常,所有数据都已正确传输(Google Chrome的过度安全偏执“除了你)无法继续“消息”。
这是SslStream
,证书链,我正在验证的方式,还是我忽略的其他问题?
更新1:我从Windows 2008R2 Active Directory证书服务器实例中获取了证书和CA证书。显然使用该证书工作正常,所以我不确定我做错了什么。我假设要么将证书链接在一起,物理生成,要么我缺少一个重要的主题,用法或扩展/增强用法。
更新2:我意识到每次软件生成新密钥时CA证书都会更改;这已被更改并锁定,我可以看到指纹和数据不会改变。仍然得到SSL-Inner-Exception: The specified data could not be decrypted
。