python - 如何更改 TLS 上下文选项

标签 python sockets ssl network-programming tls1.2

在 python 中,我们可以指定一些 TLS 上下文选项。例如,文档中的这段代码 here :

client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
client_context.options |= ssl.OP_NO_TLSv1
client_context.options |= ssl.OP_NO_TLSv1_1

我没有得到这个符号 |=。我读了它的意思,但不明白为什么我们在这里使用它?为什么我们不使用 = ?我应该使用 |= 来设置任何选项吗?奇怪的是,我发现一些例子也在他的文档中使用 &=:

ctx = ssl.create_default_context(Purpose.CLIENT_AUTH)
ctx.options &= ~ssl.OP_NO_SSLv3

我需要指定另一个选项。我只需要禁用来自此选项的 session 票证:

ssl.OP_NO_TICKET

如果我有上下文ctx,如何设置ssl.OP_NO_TICKET?我应该使用 = 还是 |=&=?请解释。

最佳答案

实际上,每个选项都是许多可能选项中的一个标志,因此您需要使用按位与 (&) 和按位或 (|) 运算组合它们.这样做是因为这些选项并不相互排斥,你需要通过选择你组合在一起的各种选项来组成一个最终值。所以每个都有一个值是 2 的幂,这意味着它在某个特定位置有点为 1,如果每个特定的单独标志打开或关闭,则最终值将进行编码。

因此您需要按位运算符来管理它们并构造您想要的最终值。

参见:

In [8]: print ssl.OP_NO_TLSv1, bin(ssl.OP_NO_TLSv1)
67108864 0b100000000000000000000000000

In [9]: print ssl.OP_NO_TLSv1_1, bin(ssl.OP_NO_TLSv1_1)
268435456 0b10000000000000000000000000000

In [13]: print ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1, bin(ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
335544320 0b10100000000000000000000000000

In [14]: print ssl.OP_NO_TLSv1 & ssl.OP_NO_TLSv1_1, bin(ssl.OP_NO_TLSv1 & ssl.OP_NO_TLSv1_1)
0 0b0

你看到如果你想要这两个选项,你需要将两个位都翻转为 1,因此需要一个 OR (|) 否则用一个 AND (&) 因为每个值只有一位设置为 1,每次都在不同的位置,所以保证结果总是 0,这意味着根本没有特征,所以肯定不是你需要的。

简而言之,在这种情况下,您永远不会使用 AND (&) 来组合值。

现在,关于&= ~:~ 是按位取反,因此在保留其他已设置选项的同时删除一些选项很有用。

ctx.options &= ~ssl.OP_NO_SSLv3

此构造使您将最终值中与 ssl.OP_NO_SSLv3 相关的位翻转为 0。

参见:

In [34]: ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)

In [37]: print ctx.options, bin(ctx.options)
2197816319 0b10000011000000000000001111111111

In [38]: print bin(ssl.OP_NO_SSLv3)
0b10000000000000000000000000

In [40]: print ctx.options & ~ssl.OP_NO_SSLv3
2164261887

In [41]: print ctx.options & ~ssl.OP_NO_SSLv3, bin(ctx.options & ~ssl.OP_NO_SSLv3)
2164261887 0b10000001000000000000001111111111

如果你比较 ctx.optionsctx.options & ~ssl.OP_NO_SSLv3 你会看到一位从 1 翻转到0,因为您实际上删除了功能 OP_NO_SSLv3

If I have context ctx, how to set ssl.OP_NO_TICKET? Should I use = or |= or &=? please explain.

这是一个您想要添加到您已有的所有其他选项的选项,因此您不想丢失它们。因此,您需要按位或 (|)。

  • 如果您只执行 = 设置此选项,但会丢失所有当前已设置的其他选项,所以不是您需要的。
  • 如果你执行|=,你会将与你想要的选项相关的位翻转为1,并且不要触及其他位;这就是你想要的!
  • 如果您执行&=,您只会翻转到 1 那些同时在您的新值和现有值中的位,这意味着如果尚未设置该值,则此处的结果只能为 0 或者相同的确切值(如果已设置):

(我的例子是用另一个值 OP_NO_TICKET 完成的,因为我那里没有它,但行为与任何一个都相同,因为每个 OP_ 值是 2n,即一位对一,所有其他位对 0)

In [16]: ctx = ssl.OP_NO_TLSv1

In [17]: print ctx, bin(ctx)
67108864 0b100000000000000000000000000

In [19]: ctx = ssl.OP_NO_TLSv1_1

In [20]: print ctx, bin(ctx)
268435456 0b10000000000000000000000000000

In [21]: ctx = ssl.OP_NO_TLSv1

In [22]: ctx |= ssl.OP_NO_TLSv1_1

In [23]: print ctx, bin(ctx)
335544320 0b10100000000000000000000000000

In [24]: ctx = ssl.OP_NO_TLSv1

In [25]: ctx &= ssl.OP_NO_TLSv1_1

In [26]: print ctx, bin(ctx)
0 0b0

请注意在 | 的情况下,两个位如何翻转为 1

关于python - 如何更改 TLS 上下文选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51672803/

相关文章:

python - 在python中将字符串系列转换为浮点列表

python - 在 python igraph 中通过源-目标-元组选择单个边

python - 如何打印函数的结果(我的 Codingbat 问题 : Warmup-1 > near_hundred) 的扩展

c - fork() - 关闭服务器

java - ZMQ (Jeromq) - 套接字发送文档中缺少参数

c# - 为什么我的证书集合中存在 .Pfx 而不是我的 .Cer?

tomcat 服务器中的 SSL 证书

docker - Nginx 代理管理器 502 Bad Gateway 错误仅在 https 模式下

python - Ctypes:将字符串从 C(++) 传输到 Python

python-3.x - Python3插槽无效- Graphite