我正在尝试通过 SSL / TLS 连接到 verifone intellinac 设备,但是我收到消息“对 SSPI 的调用失败,请参阅内部异常”内部异常表示“InnerException = {”至少传输了一个参数到函数无效"}",我已经将值更改为参数但我不知道它可以是什么。使用 .Net 4.6
我在此调用中收到的异常:
sslStream.AuthenticateAsClient(IssuerServer, xc, SslProtocols.Tls12, false);
在 intellinac 中,未使用客户端身份验证,并且启用了 TLS 1.1、1.2 和 SSLv3
演示代码如下:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SSL
{
class Program
{
static string IssuerServer;
static int IssuerPort;
static bool IssuerSSL;
private static char[] hexDigits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private static IDictionary<char, int> hexDigitsToInt = new Dictionary<char, int>() {
{'0', 0}, {'1', 1}, {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5}, {'6', 6}, {'7', 7}, {'8', 8}, {'9', 9},
{'A', 10}, {'B', 11}, {'C', 12}, {'D', 13}, {'E', 14}, {'F', 15},
{'a', 10}, {'b', 11}, {'c', 12}, {'d', 13}, {'e', 14}, {'f', 15}
};
public static byte[] StringToHex(String val, bool isLeftAligned)
{
if (val == null) return null;
int length = val.Length;
if (length % 2 == 1)
{
val = isLeftAligned ? val + "0" : "0" + val;
length++;
}
length = length / 2;
byte[] retVal = new byte[length];
char[] chars = val.ToUpper().ToCharArray();
for (int i = 0; i < length; i++)
{
char ch = chars[2 * i];
if (!hexDigitsToInt.ContainsKey(ch)) return null;
int upper = hexDigitsToInt[ch];
ch = chars[2 * i + 1];
if (!hexDigitsToInt.ContainsKey(ch)) return null;
int lower = hexDigitsToInt[ch];
retVal[i] = (byte)((upper << 4) | lower);
}
return retVal;
}
/// <summary>
///
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public static byte[] StringToHex(String val)
{
return StringToHex(val, false);
}
/// <summary>
///
/// </summary>
/// <param name="val"></param>
/// <param name="length"></param>
/// <param name="isLeftAligned"></param>
/// <returns></returns>
public static byte[] StringToHex(String val, int length, bool isLeftAligned)
{
if (val != null)
{
if (val.Length < length)
{
val = val.PadLeft(length, '0');
}
else if (val.Length > length)
{
val = val.Substring(val.Length - length, length);
}
}
return StringToHex(val, isLeftAligned);
}
/// <summary>
///
/// </summary>
/// <param name="val"></param>
/// <param name="length"></param>
/// <returns></returns>
public static byte[] StringToHex(String val, int length)
{
return StringToHex(val, length, false);
}
static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine("certificate.Subject [{0}]", certificate.Subject);
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers.
return false;
}
static void Tx()
{
TcpClient client = null;
NetworkStream netStream = null;
SslStream sslStream = null;
try
{
IssuerSSL = true;
IssuerServer = "191.103.83.42";
IssuerPort = 8019;
byte[] byBufferOut = StringToHex("012F60000600000320703E05800EC0021616496078001122017200000100000006313400019810350602102501000000510006003130343131303030303032343339313030363030303337393235393937333030303030343937202020202001365F2A0203405F34010182021C008407A0000000031010950580200080009A032102109C01009F02060000000554789F03060000000000009F0902008D9F100706010A03A000009F1A0203409F1E0856545350303030329F26081E8CE9CD139D79899F2701809F3303E0B0C89F34031E03009F3501229F360200389F37047371B2F99F41040000000400224D5330323030303030303234454D3735303030303130000630303030323300380014333930303030303030303736353600143832303030303030303038333232000431434530");
int totalBytesRcvd = 0;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
client = new TcpClient(IssuerServer, IssuerPort);
netStream = client.GetStream();
sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
X509Certificate2Collection xc = new X509Certificate2Collection();
sslStream.AuthenticateAsClient(IssuerServer, xc, SslProtocols.Tls12, false);
sslStream.Write(byBufferOut, 0, byBufferOut.Length);
sslStream.Flush();
sslStream.ReadTimeout = 120000;
client.ReceiveBufferSize = 4000;
if (netStream.CanRead)
{
byte[] readBuffer = new byte[client.ReceiveBufferSize];
using (var writer = new MemoryStream())
{
do
{
int numberOfBytesRead = 0;
numberOfBytesRead = sslStream.Read(readBuffer, 0, readBuffer.Length);
if (numberOfBytesRead <= 0)
{
throw new Exception("Connection closed prematurely.");
}
writer.Write(readBuffer, 0, numberOfBytesRead);
totalBytesRcvd += numberOfBytesRead;
} while (netStream.DataAvailable);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + " || " + ex.InnerException.Message );
}
finally
{
if (sslStream != null)
{
sslStream.Flush();
sslStream.Close();
}
if (netStream != null)
{
netStream.Flush();
netStream.Close();
}
if (client != null)
{
client.Close();
}
}
}
static void Main(string[] args)
{
Tx();
Console.ReadKey();
}
}
}