При попытке перейти от реализации SSL на основе C к C # с использованием .NET SslStream, мы столкнулись с проблемами совместимости шифров с .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);
}
}
}