- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在使用 C# 中的 OpenSSL
时遇到了一个奇怪的问题。
事实:我已经为 C#
编写了一个包装器,它工作得很好,它可以连接到其他 SSL
服务器,或者接受来自 SSL< 的连接
客户。我的包装器仅使用内存 BIO。每当我将 MEM
BIO 连接到任何类型套接字的输入和输出时,握手成功,数据传输工作,所以问题是不在 wrapper 中。
我用这个包装器制作了两个程序,一个客户端和一个服务器,它们建立了 ssl session ,当我尝试将数据从服务器发送到客户端(或相反的方式)时,另一端回显它由于某种原因发送到发送方,数据流量非常慢(即使在本地环回中也最大 20kB/s,如果我尝试以更高的速度发送,例如在 SSL_read()
中抽取更多数据,然后在 TCP 上使用 TLS有很大的延迟,UDP 上的 DTLS 有时会有 75% 的数据包丢失),所以我决定用包装器对 OpenSSL 进行基准测试,因为某些方法或错误的参数可能会减慢运行速度。
我的想法是在一个程序中初始化两个 SSL
上下文,一个客户端和一个服务器,将它们的 Memory BIO 相互连接 (RX-TX TX-RX)
, 并开始握手。
我就是不能让他们成功完成握手!
在 Clienthello 之后使用 DTLS1,服务器开始以 4 个数据包(3x256 字节 + 145)响应 Serverhello 和 Cert 数据,但在第一个数据包之后客户端警告:
After writing to CLIENT (packet: 2): 22016:error:14102044:SSL routines:dtls1_read_bytes:internal error:.\ssl\d1_pkt.c:1370:
After writing to CLIENT (packet: 3): 22016:error:14102044:SSL routines:dtls1_read_bytes:internal error:.\ssl\d1_pkt.c:1370:
After writing to CLIENT (packet: 4): 22016:error:14102044:SSL routines:dtls1_read_bytes:internal error:.\ssl\d1_pkt.c:1370:
After writing to CLIENT (packet: 5): 22016:error:14102044:SSL routines:dtls1_read_bytes:internal error:.\ssl\d1_pkt.c:1370:
两个 session 之间的数据包流如下:
Client -> 178 -> Server
Server -> 256 -> Client
Server -> 256 -> Client
Server -> 256 -> Client
Server -> 145 -> Client
Client -> 15 -> Server
我已经用 Wireshark
分析了这些数据包(在文件转储之后),一切似乎都正常(这个分析不是上面的数据包,而是问题的相同重现): http://reset.tor.hu/ssl/sima/programom_dtls1.txt
在此之后我得到更多的错误:
After writing to SERVER (packet: 5): 22016:error:141020E5:SSL routines:dtls1_read_bytes:ssl handshake failure:.\ssl\d1_pkt.c:819:
Before writing to SERVER (packet: 6): 22016:error:140FD10F:SSL routines:DTLS1_GET_MESSAGE_FRAGMENT:bad length:.\ssl\d1_both.c:892:
After writing to SERVER (packet: 6): 22016:error:14102417:SSL routines:dtls1_read_bytes:sslv3 alert illegal parameter:.\ssl\d1_pkt.c:1200:SSL alert number 47
22016:error:141020E5:SSL routines:dtls1_read_bytes:ssl handshake failure:.\ssl\d1_pkt.c:819:
我唯一可用的想法是调试这个问题,以便在从 BIO 读取数据包后立即将数据包转储到文件,然后在另一个 session 中将数据包写入 BIO 之前,但我发现没有任何区别字节比较后的内容,包顺序也OK。
文件转储在这里:http://reset.tor.hu/ssl/y/direct_bio_error/
我无法想象会出现什么问题,因为他们从来没有在没有失败的情况下完成握手,所以我决定向这个程序添加两个 UDP 套接字,并将套接字连接到 BIO 并相互连接,并且毫不奇怪,第一次握手就成功了。
文件转储在这里:http://reset.tor.hu/ssl/y/socket_ok/
可见,文件内容或数据包序列没有任何区别。
那为什么他们不直接连接 BIO 工作呢?!
您可以在该视频中看到产生错误和正常工作的程序:https://www.youtube.com/watch?v=4crbSz6JMMY
出于某种原因,当时我唯一的想法是使用 C# 混合方法调用,但我没有使用任何线程!非托管代码调用回调来读出 BIO,我将 BIO 读出到我的缓冲区,我调用另一个方法将缓冲区写入 BIO 并在非托管代码中调用 SSL_read()
,以使用BIO 中的数据。而这恰恰是另一种方式。如果我不使用缓冲区,而是使用套接字,它就可以工作。套接字可以做什么使其工作?
我什至尝试将 Thread.Sleep(100) 放在 BIO 著作之间,但没有帮助,实际上超过 140ms OpenSSL
崩溃了(但对于套接字,它甚至可以在 1000ms 时工作,甚至更奇怪)。
direct BIO 和慢速流量问题的问题和解决方案是什么?
提前感谢您的回答!
最佳答案
好吧,实际上我似乎刚刚解决了 Direct-Memory-BIO-Handshake 问题。
建议在BIO_write()
之后调用SSL_read()
,否则OpenSSL
不会检查READ BIO中的数据和不会处理它,所以几乎每次都是写到BIO后直接使用。
如果将 OpenSSL
上下文配置为 CLIENT,则在 BIO_write()
之后不应使用 SSL_read()
> 直接直到握手未完成!
如果 OpenSSL
与 socket 一起使用(即使是内存 bio),如果我们在 BIO_write()
之后直接使用 SSL_read()
就可以正常工作,但两个 session 之间没有直接 BIO 连接。至少作为 C# 中的非托管代码!
有效的BIO写法如下:
public bool BIO_Write(byte[] data)
{
if (Inited & data.Length > 0)
{
Wrapper.BIO_write(BIOR, data, data.Length);
if (isServer(SSL_method))
{
// For SERVER MODE
if (Wrapper.SSL_is_init_finished(SSL))
{
readFromSSL();
}
else
{
Wrapper.SSL_do_handshake(SSL);
}
}
else
{
// For CLIENT MODE
if (Wrapper.SSL_is_init_finished(SSL))
{
readFromSSL();
}
else
{
// It is extremely important to call the SSL_do_handshake()
// only if SSL_want() returns 3, otherwise OpenSSL will
// throw a FATAL ERROR and crash with direct BIO connection
// return value 3 is SSL_ERROR_WANT_WRITE
if (Wrapper.SSL_want(SSL) == 3)
{
Wrapper.SSL_do_handshake(SSL);
}
}
}
return true;
}
else
{
return false;
}
}
我希望这会对某人有所帮助!
关于c# - 两个 session 和直接连接内存 BIO 的 C# 的 OpenSSL 握手失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33382447/
在进行 BIOS 开发时,我看到了对英特尔 BIOS 引用设计和英特尔固件支持包 (FSP) 的引用。英特尔是否积极支持两者,或者引用设计正在逐步淘汰以支持 FSP。 最佳答案 为了创建 FSP,引用
我知道有一些程序,比如 lojack 用于安装在 BIOS 上的笔记本电脑,但我仍然有点困惑。在阅读有关 lojack 的信息时,在我看来,在用户登录并尝试访问互联网之前,他们无法完全定位笔记本电脑的
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 8年前关闭。 Improve thi
我对 BIO 例程 BIO_read()/BIO_write() 和 SSL_read()/ 之间的区别感到困惑SSL_write() 当 BIO 是内存 BIO 而不是套接字 BIO 时。 我正在尝
我想知道什么样的序列号wmic bios get serialnumber Windows命令实际上给了你什么? 是你主板的序列号吗?文档对此不清楚。 最佳答案 wmic bios get seria
我正在尝试使用 OpenSSL 在 C++ 中创建一个简单的 FTP/FTPS 客户端实现。我已经设法使用 BIO API 与普通 FTP 一起工作。现在的问题是:一旦我有一个不安全的连接和 BIO
pe启动acpl bios error是一个非常简单解决的问题,一般都是主板不支持支持ACPI造成的,只要禁用一下就可以解决了,想要解决的用户可以来看看详细的内容。 pe启动acpl b
这里是代码的上下文: void THREAD_CC server_thread(void *arg) { BIO *client = (BIO *)arg; ... } 表达式
我正在使用 UEFI EDK2 创建 BIOS。我修改了 FDF 以将驱动程序(UEFI 和旧版本)从主固件卷移动到我严格创建的单独固件卷 (FV) 以保存驱动程序。 在我从主 FV 移动驱动程序之前
我们正在运行 32 位和 64 位的 windows xp pro service pack 3。我们正在使用 WMI 来获取 BIOS 制造商和型号,但我们确实更喜欢使用 Win32 API 或汇编
OpenSSL 中的 BIO 对到底是什么?它的用途是什么?我已经检查过 OpenSSL 文档,但任何细节都很少。 最佳答案 OpenSSL 中的 BIO 类似于文件句柄。您可以使用一对它们来安全地相
在此示例代码中: BIO *bio1 = BIO_new(BIO_s_mem()); BIO *bio2 = BIO_new(BIO_s_mem()); SSL_set_bio(ssl, bio1,
我试图将 QEMU 与我正在构建的内核 ISO 一起使用,但我无法运行测试。 我使用的是 Windows 10 64 位,并添加了 pc-bios如果这很重要,请将文件夹添加到 PATH。 到目前为止
我处于不幸的情况,我需要使用 BIOS 未在 ia32 功能控制 MSR 寄存器中启用的 CPU 功能。 BIOS 确实设置了锁定位,因此我无法自己设置该位。 BIOS (Asus UEFI BIOS
我升级了我的 mac 安装,Mountain Lion 10.8.4,但现在每次我尝试加载 Android AVD 时“Eclipse”都会出错。返回的错误是这样的: qemu: 无法加载 PC BI
下面是一些示例代码,展示了我如何使用 OpenSSL: BIO *CreateMemoryBIO() { if (BIO *bio = BIO_new(BIO_s_mem())) {
BIOS 是用汇编语言编写的,机器只能理解二进制文件。 BIOS 是系统启动时加载到内存中的第一个程序。什么编译BIOS生成二进制文件? 最佳答案 BIOS 工程师用 x86 汇编语言编写 BIOS,
使用 OpenGL VBO 时,您可以交错数据 例如,您甚至可以将顶点数据与供 CPU 而不是 GPU 使用的其他数据交错。 交错是有助于还是阻碍主流独立显卡和集成显卡的性能? 最佳答案 一般的答案是
我目前正在编写一个引导加载程序,旨在加载一个比引导扇区允许的时间更长的程序。但是,每次运行程序(我在Virtualbox和QEMU中都测试过),磁盘读取失败,磁盘重置也失败。 bootloader 被
我正在开发一个操作系统项目,使用 isolinux (syslinux 4.5) 作为引导加载程序,加载我的内核与组织在 0x200000 的多重引导头文件。 据我所知,内核已经处于 32 位保护模式
我是一名优秀的程序员,十分优秀!