- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
你好,我有一个使用 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);
我在这个 C++ 应用程序中使用静态 ssl 库,我从 here 下载
一切正常,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)。所以基本上我的问题是,将 .net 套接字与 openssl 一起使用可能有什么问题? (因为 C++ 应用程序可以完美地处理相同类型的代码)。
更新:我尝试使用 OPENSSL_add_all_algorithms_conf 但它似乎没有任何改变......我求你帮忙!!
最佳答案
据我所知,System.Net.Sockets 类不支持 SSL。经过一些研究,它看起来像是在 System.Net.Security 和 System.Security.Authentication 中......
这是一个 MS 示例的链接... http://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.110).aspx
此示例向服务器发送一条消息,然后断开连接。我写了一个类似的(非 SSL)客户端,它是全双工的(异步发送和接收)。您可以使用某些 MS 示例调整我的示例以通过 SSL 进行通信。
在这里...希望它有所帮助...如果您将其改编为 SSL,请告诉我,因为我可能需要做同样的事情。
using System;
using System.Text;
using System.Net.Sockets;
using System.Collections.Generic;
namespace MyNamespace.Utilities
{
public class StateObject{
public Socket workSocket = null;
public const int BUFFER_SIZE = 1024;
public byte[] buffer = new byte[BUFFER_SIZE];
//public StringBuilder message = new StringBuilder();
}
public class FullDuplexSocket : IDisposable
{
public event NewMessageHandler OnMessageReceived;
public delegate void NewMessageHandler(string Message);
public event DisconnectHandler OnDisconnect;
public delegate void DisconnectHandler(string Reason);
private Socket _socket;
private bool _useASCII = true;
private string _remoteServerIp = "";
private int _port = 0;
private bool _allowRetry = true;
/// <summary>
/// Constructer of a full duplex client socket. The consumer should immedately define
/// and event handler for the OnMessageReceived event after construction has completed.
/// </summary>
/// <param name="RemoteServerIp">The remote Ip address of the server.</param>
/// <param name="Port">The port that will used to transfer/receive messages to/from the remote IP.</param>
/// <param name="UseASCII">The character type to encode/decode messages. Defaulted to use ASCII, but setting the value to false will encode/decode messages in UNICODE.</param>
public FullDuplexSocket(string RemoteServerIp, int Port, bool UseASCII = true)
{
_useASCII = UseASCII;
_remoteServerIp = RemoteServerIp;
_port = Port;
Initialize();
}
private void Initialize()
{
try //to create the socket and connect
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Connect(_remoteServerIp, _port);
}
catch (Exception e)
{
throw new Exception("Unable to connect to the remote Ip.", e);
}
try //to listen to the socket
{
StateObject stateObject = new StateObject();
stateObject.workSocket = _socket;
_socket.BeginReceive
(
stateObject.buffer, //Buffer to load in our state object
0, //Start at the first position in the byte array
StateObject.BUFFER_SIZE, //only load up to the max per read
0, //Set socket flags here if necessary
new AsyncCallback(ReadFromSocket), //Who to call when data arrives
stateObject //state object to use when data arrives
);
_allowRetry = true;
}
catch (Exception e)
{
throw new Exception("Unable to start listening to the socket.", e);
}
}
/// <summary>
/// This will read the bytes from the socket, convert the bytes to a string and fire the OnMessageReceived event.
/// If the socket is forcibly closed, the OnDisconnect event will be fired. This happens when the other side of
/// the socket connection on the remote Ip is no longer available.
/// </summary>
/// <param name="asyncResult"></param>
public void ReadFromSocket(IAsyncResult asyncResult)
{
StateObject stateObject = (StateObject)asyncResult.AsyncState; //pull out the state object
int bytesReceived = 0;
try //to receive the message.
{
bytesReceived = stateObject.workSocket.EndReceive(asyncResult);
}
catch (Exception e) //Exception will occur if connection was forcibly closed.
{
RaiseOnDisconnect(e.Message);
return;
}
if (bytesReceived > 0)
{
RaiseOnMessageReceived
(
_useASCII ?
Encoding.ASCII.GetString(stateObject.buffer, 0, bytesReceived) :
Encoding.Unicode.GetString(stateObject.buffer, 0, bytesReceived)
);
try //The BeginRecieve can file due to network issues. _allowRetry allows a single failure between successful connections.
{
if (_allowRetry)
{
stateObject.workSocket.BeginReceive
(
stateObject.buffer, //Buffer to load in our state object
0, //Start at the first position in the byte array
StateObject.BUFFER_SIZE, //only load up to the max per read
0, //Set socket flags here if necessary
new AsyncCallback(ReadFromSocket), //Who to call when data arrives
stateObject //state object to use when data arrives
);
}
}
catch
{
_allowRetry = false;
}
}
else
{
stateObject.workSocket.Close();
RaiseOnDisconnect("Socket closed normally.");
return;
}
}
/// <summary>
/// Broadcast a message to the IP/Port. Consumer should handle any exceptions thrown by the socket.
/// </summary>
/// <param name="Message">The message to be sent will be encoded using the character set defined during construction.</param>
public void Send(string Message)
{
//all messages are terminated with /r/n
Message += Environment.NewLine;
byte[] bytesToSend = _useASCII ?
Encoding.ASCII.GetBytes(Message) :
Encoding.Unicode.GetBytes(Message);
int bytesSent = _socket.Send(bytesToSend);
}
/// <summary>
/// Clean up the socket.
/// </summary>
void IDisposable.Dispose()
{
try
{
_socket.Close();
RaiseOnDisconnect("Socket closed via Dispose method.");
}
catch { }
try
{
_socket.Dispose();
}
catch { }
}
/// <summary>
/// This method will gracefully raise any delegated events if they exist.
/// </summary>
/// <param name="Message"></param>
private void RaiseOnMessageReceived(string Message)
{
try //to raise delegates
{
OnMessageReceived(Message);
}
catch { } //when none exist ignore the Object Reference Error
}
/// <summary>
/// This method will gracefully raise any delegated events if they exist.
/// </summary>
/// <param name="Message"></param>
private void RaiseOnDisconnect(string Message)
{
try //to raise delegates
{
OnDisconnect(Message);
}
catch { } //when none exist ignore the Object Reference Error
}
}
}
关于c# 与 c++ ssl_connect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20009376/
我使用非阻塞套接字。对于普通的 TCP 连接,我在这里执行: Non blocking socket - how to check if a connection was successful? 但是
我正在尝试使用 SSL 创建服务器-客户端程序。我在使用 SSL_connect() 时遇到了一些麻烦:当我调用它时,它不会再返回,它只是卡在那里,客户端程序一直在运行,服务器停止等待握手完成。一旦我
我目前正在将一些曾经使用 RSA Security 库的现有技术重写到 OpenSSL 中,但我开始遇到一些问题。目前,所有证书验证代码似乎都在顺利运行,直到我调用 SSL_connect()。 之前
这两天,当我尝试安装新的 gem 时,我的控制台上收到了这个错误: Gem::RemoteFetcher::FetchError: SSL_connect returned=1 errno=0 sta
我正在尝试通过 TLSv1.2 建立 https 连接。上下文创建和一切都很好,我没有包含在下面的代码中。 if(https) //block 1 { int ssl_err = 0;
我在使用 openssl 库时遇到问题。我在发送 EHLO 和 STARTTLS 后调用以下函数: SSL_CTX *ctx = NULL; SSL *ssl = NULL; void Cre
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and t
我有一个非阻塞套接字,我正在使用 openssl 创建一个 ssl 连接。我的问题是 SSL_connect 的工作方式。在这些情况下,它返回 SSL_ERROR_WANT_READ 或 SSL_ER
你好,我有一个使用 openssl 和 winapi 套接字的 C++ 应用程序,代码如下所示: sock = socket(AF_INET, SOCK_STREAM, 0); if (con
SSL_connect() 是否支持 ssl v3?我问这个的原因是,在访问网站时: https://secure53.onlineaccess1.com 我得到 SSL_connect(ssl) 的
我们有基于 Cucumber 的 UI 自动化测试框架。最近我们已经从 Ruby 1.9.x 迁移到 2.2.0,之后我们在通过测试框架登录我们的应用程序时遇到了问题。它说 SSL 连接重置问题。 错
我刚刚开始学习 C 的 openssl。我在弄清楚 SSL_set_connect_state 之间的区别时遇到了一些麻烦。函数和 SSL_connect功能,因为他们似乎在我的系统上做同样的事情。有
几天来,我一直在努力解决这个问题,想弄清楚它们是如何工作的。我已经阅读了文档并查看了一些示例,但我仍然需要指导。 具体来说,当客户端调用 connect() 并成功连接到服务器主机时,我是否应该在它之
使用我的 SSLCLIENT 的 openssl SSLConnect 出现奇怪的连接失败。 我们正在尝试与服务器建立 ssl 连接。我们注意到 SSL_CONNECT 失败,错误代码为“SSL_ER
当用 openssl 编写的服务器不调用 SSL_accept 时,客户端的 SSL_connect 将永远阻塞。openssl -SSL_CTX_set_timeout 、 SSL_SESSION_
SSL_CTX_set_verify() 和 SSL_set_verify() 调用可用于为底层上下文和 ssl 设置 verify_callback() 函数,分别。以下是 verify_callb
以下代码将始终以 # 结尾错误信息。 它可能会在 5 秒后或 30 分钟后失败。 require 'net/https' http = Net::HTTP.new('newproduct.zendes
我有以下 Controller - courses-controller.rb: class CoursesController Searching for - Imag
我有以下代码,并且我收到了 SIGSEGV: if ( SSL_connect(ssl) == FAIL ) 我遇到的错误是: Program received signal SIGSEGV, Seg
我想在我的 C++ 服务器和客户端中使用 thrift 提供的 ssl 支持。我自己的 Thrift 客户端在通过“transport->open()”后总是卡在 SSL_connect 中.所以我建
我是一名优秀的程序员,十分优秀!