在尝试使用.NET SslStream从基于'C'的SSL实现转移到C#时,我们遇到了与.NET SslStream和AS400机器的密码兼容性问题,我们正在尝试连接到(曾经工作过。)
当我们调用SslStream.AuthenticateAsClient时,它发送以下内容:
16 03 00 00 37 01 00 00 33 03 00 4d 2c 00 ee 99 4e 0c 5d 83 14 77 78 5c 0f d3 8f 8b d5 e6 b8 cd 61 0f 29 08 ab 75 03 f7 fa 7d 70 00 00 0c 00 05 00 0a 00 13 00 04 00 02 00 ff 01 00
其解码为(基于http://www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt)
[16] Record Type
[03 00] SSL Version
[00 37] Body length
[01] SSL3_MT_CLIENT_HELLO
[00 00 33] Length (51 bytes)
[03 00] Version number = 768
[4d 2c 00 ee] 4 Bytes unix time
[… ] 28 Bytes random number
[00] Session number
[00 0c] 12 bytes (2 * 6 Cyphers)?
[00 05, 00 0a, 00 13, 00 04, 00 02, 00 ff] -> [RC4, PBE-MD5-DES, RSA, MD5, PKCS, ???]
[01 00] Null compression method
as400服务器响应:
15 03 00 00 02 02 28
[15] SSL3_RT_ALERT
[03 00] SSL Version
[00 02] Body Length (2 Bytes)
[02 28] 2 = SSL3_RT_FATAL, 40 = SSL3_AD_HANDSHAKE_FAILURE
我特意想在解码器的末尾解码'00 FF'。 我是否正确解码了?什么,如果有的话,'00 FF'也会解码?
我使用以下代码测试/重现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.IO;
using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;
namespace TestSslStreamApp
{
class DebugStream :
Stream
{
private Stream AggregatedStream { get; set; }
public DebugStream(Stream stream) { AggregatedStream = stream; }
public override bool CanRead { get { return AggregatedStream.CanRead; } }
public override bool CanSeek { get { return AggregatedStream.CanSeek; } }
public override bool CanWrite { get { return AggregatedStream.CanWrite; } }
public override void Flush() { AggregatedStream.Flush(); }
public override long Length { get { return AggregatedStream.Length; } }
public override long Position
{
get { return AggregatedStream.Position; }
set { AggregatedStream.Position = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
int bytesRead = AggregatedStream.Read(buffer, offset, count);
return bytesRead;
}
public override long Seek(long offset, SeekOrigin origin) { return AggregatedStream.Seek(offset, origin); }
public override void SetLength(long value) { AggregatedStream.SetLength(value); }
public override void Write(byte[] buffer, int offset, int count)
{
AggregatedStream.Write(buffer, offset, count);
}
}
class Program
{
static void Main(string[] args)
{
const string HostName = "as400";
TcpClient tcpClient = new TcpClient(HostName, 992);
SslStream sslStream = new SslStream(new DebugStream(tcpClient.GetStream()), false, null, null,
EncryptionPolicy.AllowNoEncryption);
sslStream.AuthenticateAsClient(HostName, null, SslProtocols.Ssl3, false);
}
}
}
答案 0 :(得分:3)
来源:RFC 5746 TLS Renegotiation Extension
3.3. Renegotiation Protection Request Signaling Cipher Suite Value Both the SSLv3 and TLS 1.0/TLS 1.1 specifications require implementations to ignore data following the ClientHello (i.e., extensions) if they do not understand it. However, some SSLv3 and TLS 1.0 implementations incorrectly fail the handshake in such a case. This means that clients that offer the "renegotiation_info" extension may encounter handshake failures. In order to enhance compatibility with such servers, this document defines a second signaling mechanism via a special Signaling Cipher Suite Value (SCSV) "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", with code point {0x00, 0xFF}. This SCSV is not a true cipher suite (it does not correspond to any valid set of algorithms) and cannot be negotiated. Instead, it has the same semantics as an empty "renegotiation_info" extension, as described in the following sections. Because SSLv3 and TLS implementations reliably ignore unknown cipher suites, the SCSV may be safely sent to any server. The SCSV can also be included in the SSLv2 backward compatible CLIENT-HELLO (see Appendix E.2 of [RFC5246]).
答案 1 :(得分:0)
最简单的方法是检查您的C实现发送是什么,并查看它请求的SSL版本和密码套件,然后,看看服务器正在响应什么 - SSL版本和选择的密码套件。