大家好,我有一个使用OpenSSL和WinAPI套接字的C++应用程序,代码如下:
sock = socket(AF_INET, SOCK_STREAM, 0);
if (connect(my_sock, (struct sockaddr*)&dest_addr, sizeof(dest_addr))==0) {
WSAIoctl(my_sock, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),NULL, 0, &dwSize, NULL, NULL);
}
}
.....
SSL_load_error_strings();
SSL_library_init();
ctx = SSL_CTX_new(SSLv23_client_method());
if(!ctx)
{
return false;
}
ssl = SSL_new(ctx);
SSL_CTX_free(ctx);
if(!ssl)
{
return false;
}
SSL_set_fd(ssl, (int)sock); //making the socket use ssl mode
result = SSL_connect(ssl);
我正在使用静态SSL库与这个C++应用程序,我从这里下载了它。
一切工作正常,ssl_connect返回1。但我需要做的是使用C#重新编写此代码。因此,我尝试了一下,C#代码看起来像这样:
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSL_read")]
public static extern int SSL_Read(IntPtr ssl, ref byte[] buf, int num);
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSL_write")]
public static extern int SSL_Write(IntPtr ssl, byte[] buf, int num);
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSL_set_fd")]
extern public static int SSL_set_fd(IntPtr ssl, int fd);
[DllImport("ssleay32.dll", CallingConvention= CallingConvention.Cdecl, EntryPoint = "SSL_CTX_new")]
extern public static IntPtr SSL_CTX_new(IntPtr method);
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSL_new")]
extern public static IntPtr SSL_new(IntPtr ctx);
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSL_connect")]
extern public static int SSL_connect(IntPtr ssl);
[DllImport("ssleay32.dll",CallingConvention= CallingConvention.Cdecl, EntryPoint = "SSL_load_error_strings")]
extern public static void SSL_load_error_strings();
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSL_library_init")]
extern public static int SSL_library_init();
[DllImport("ssleay32.dll",CallingConvention= CallingConvention.Cdecl, EntryPoint = "SSLeay_add_all_algorithms")]
extern public static int SSLeay_add_all_algorithms();
[DllImport("ssleay32.dll",CallingConvention= CallingConvention.Cdecl, EntryPoint = "SSLv23_client_method")]
extern public static IntPtr SSLv23_client_method();
[DllImport("ssleay32.dll",CallingConvention= CallingConvention.Cdecl, EntryPoint = "SSLv3_client_method")]
extern public static IntPtr SSLv3_client_method();
[DllImport("ssleay32.dll",CallingConvention= CallingConvention.Cdecl, EntryPoint = "SSL_CTX_free")]
extern public static void SSL_CTX_free(IntPtr ctx);
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSL_free")]
extern public static void SSL_free(IntPtr ssl);
[DllImport("ssleay32.dll",CallingConvention= CallingConvention.Cdecl, EntryPoint = "SSL_get_error")]
extern public static int SSL_get_error(IntPtr ssl, int ret);
[DllImport("ssleay32.dll",CallingConvention= CallingConvention.Cdecl, EntryPoint = " SSL_CTX_set_mode")]
extern public static long SSL_CTX_set_mode(IntPtr ctx, long mode);
[DllImport("libeay32", CallingConvention = CallingConvention.Cdecl, EntryPoint = "OPENSSL_add_all_algorithms_noconf")]
extern public static void OpenSSL_add_all_algorithms();
[DllImport("libeay32", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ERR_get_error")]
extern public static int ERR_get_error();
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSL_CTX_ctrl")]
public extern static int SSL_CTX_ctrl(IntPtr ctx, int cmd, int arg, IntPtr parg);
[DllImport("ssleay32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SSLv23_method")]
public extern static IntPtr SSLv23_method();
public bool Ssl_Init()
{
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
SSL_library_init();
IntPtr method = SSLv23_client_method();
IntPtr ctx = SSL_CTX_new(method);
if (ctx == IntPtr.Zero)
{
return false;
}
_ssl = SSL_new(ctx);
if (_ssl == IntPtr.Zero)
{
return false;
}
int val = SSL_set_fd(_ssl, this.socket.Handle.ToInt32()); //always returns 1
int result = SSL_connect(_ssl);
if(result!=1) return false;
SSL_CTX_free(ctx);
Ssl_Enabled.Set();
return true;
}
我使用以下代码创建了c#套接字:
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.socket.Connect(host,port);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1000);
我在我的c#代码中经常得到SSL_Connect = 0,同时SSL_get_error() = 5(error_syscall)。因此,我的问题基本上是,使用openssl和.net socket可能有什么问题?(因为使用相同类型的代码的c++应用程序可以完美地工作)。
更新:我尝试使用OPENSSL_add_all_algorithms_conf,但似乎没有改变任何事情...我恳求您的帮助!!