Skip to content

Commit 908c125

Browse files
zhangweiJonathan Corbet
authored andcommitted
docs/zh_CN: Add siphash index Chinese translation
Translate lwn/Documentation/security/siphash.rst into Chinese Update the translation through commit 12fe434 ("Documentation: siphash: Fix typo in the name of offsetofend macro") Reviewed-by: Yanteng Si <[email protected]> Signed-off-by: zhangwei <[email protected]> Reviewed-by: Yanteng Si <[email protected]> Signed-off-by: Jonathan Corbet <[email protected]> Link: https://lore.kernel.org/r/0af3d9b8be0e5166f74bd36fd6b040767f767fce.1736315479.git.zhangwei@cqsoftware.com.cn
1 parent ef3d720 commit 908c125

File tree

2 files changed

+196
-1
lines changed

2 files changed

+196
-1
lines changed

Documentation/translations/zh_CN/security/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
:maxdepth: 1
1717

1818
lsm
19+
siphash
1920
digsig
2021

2122
TODOLIST:
@@ -27,7 +28,6 @@ TODOLIST:
2728
* sak
2829
* SCTP
2930
* self-protection
30-
* siphash
3131
* tpm/index
3232
* landlock
3333
* secrets/index
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
.. include:: ../disclaimer-zh_CN.rst
3+
:Original: Documentation/security/siphash.rst
4+
5+
:翻译:
6+
7+
张巍 zhangwei <[email protected]>
8+
9+
=====================================
10+
SipHash - 一种短输入伪随机函数(PRF)
11+
=====================================
12+
13+
:作者: Jason A.Donenfeld <[email protected]>
14+
15+
SipHash是一种加密安全的伪随机函数,即一种用于生成伪随机密钥的哈
16+
希函数,因为其在处理短输入时表现出色,因此得名。其由密码学家
17+
Daniel J. Bernstein和Jean-Philippe Aumasson设计。目的主要是替
18+
代其他哈希函数,例如:jhash,md5_transform,sha1_transform等。
19+
20+
SipHash采用一个完全由随机数生成的密钥,以及一个输入缓冲区或者
21+
多个输入整数,它输出一个与随机数难以区分的整数,你可以将它作
22+
为安全序列、安全cookies的一部分,或者对其进行掩码处理,以便在
23+
哈希表中使用。
24+
25+
生成密钥
26+
========
27+
28+
密钥应来源于加密安全的随机数生成,要么使用get random bytes
29+
要么使用get random once::
30+
31+
siphash_key_t key;
32+
get_random_bytes(&key, sizeof(key));
33+
34+
如果你的密钥来源不是这两个,那么你的做法是错的。
35+
36+
使用函数
37+
========
38+
39+
这个函数有两个变种,一种是接受整数列表,另一种是接受缓冲区::
40+
41+
u64 siphash(const void *data, size_t len, const siphash_key_t *key);
42+
43+
和::
44+
45+
u64 siphash_1u64(u64, const siphash_key_t *key);
46+
u64 siphash_2u64(u64, u64, const siphash_key_t *key);
47+
u64 siphash_3u64(u64, u64, u64, const siphash_key_t *key);
48+
u64 siphash_4u64(u64, u64, u64, u64, const siphash_key_t *key);
49+
u64 siphash_1u32(u32, const siphash_key_t *key);
50+
u64 siphash_2u32(u32, u32, const siphash_key_t *key);
51+
u64 siphash_3u32(u32, u32, u32, const siphash_key_t *key);
52+
u64 siphash_4u32(u32, u32, u32, u32, const siphash_key_t *key);
53+
54+
如果向一个通用的hsiphash函数传递一个恒定长度的常量,他将
55+
在编译的时候将常量折叠,并自动选择一个优化后的函数。
56+
57+
哈希表键函数的用法::
58+
59+
struct some_hashtable {
60+
DECLARE_HASHTABLE(hashtable, 8);
61+
siphash_key_t key;
62+
};
63+
64+
void init_hashtable(struct some_hashtable *table)
65+
{
66+
get_random_bytes(&table->key, sizeof(table->key));
67+
}
68+
69+
static inline hlist_head *some_hashtable_bucket(struct some_hashtable *table, struct interesting_input *input)
70+
{
71+
return &table->hashtable[siphash(input, sizeof(*input), &table->key) & (HASH_SIZE(table->hashtable) - 1)];
72+
}
73+
74+
然后,你可以像往常一样对返回的哈希存储桶进行迭代。
75+
76+
安全性
77+
======
78+
79+
SipHash有着非常高的安全性,因为其有128位的密钥。只要密钥是保密的,
80+
即使攻击者看到多个输出,也无法猜测出函数的正确输出,因为2^128次
81+
方个输出是非常庞大的。
82+
83+
Linux实现了SipHash的“2-4”变体
84+
85+
Struct-passing陷阱
86+
==================
87+
88+
通常情况下,XuY函数的输出长度不够大,因此你可能需要传递一个预填充
89+
的结构体给SipHash,在这样做时,务必确保结构体没有填充空隙,最简单
90+
的方法就是将结构体的成员按照大小降序的方式排序,并且使用offsetofend()
91+
函数代替sizeof()来获取结构体大小,出于性能的考虑,如果可以的话,最
92+
好将结构体按右边界对齐,示例如下::
93+
94+
const struct {
95+
struct in6_addr saddr;
96+
u32 counter;
97+
u16 dport;
98+
} __aligned(SIPHASH_ALIGNMENT) combined = {
99+
.saddr = *(struct in6_addr *)saddr,
100+
.counter = counter,
101+
.dport = dport
102+
};
103+
u64 h = siphash(&combined, offsetofend(typeof(combined), dport), &secret);
104+
105+
资源
106+
====
107+
108+
如果你有兴趣了解更多信息,请阅读SipHash论文:
109+
https://131002.net/siphash/siphash.pdf
110+
111+
-------------------------------------------------------------------------------
112+
113+
===========================================
114+
HalfSipHash 是 SipHash 的一个较不安全的变种
115+
===========================================
116+
117+
:作者: Jason A.Donenfeld <[email protected]>
118+
119+
如果你认为SipHash的速度不够快,无法满足你的需求,那么你可以
120+
使用HalfSipHash,这是一种令人担忧但是有用的选择。HalfSipHash
121+
将SipHash的轮数从“2-4”降低到“1-3”,更令人担心的是,它使用一
122+
个容易被穷举攻击的64位密钥(输出为32位),而不是SipHash的128位
123+
密钥,不过,这对于要求高性能“jhash”用户来说这是比较好的选择。
124+
125+
HalfSipHash是通过 "hsiphash" 系列函数提供的。
126+
127+
.. warning::
128+
绝对不要在作为哈希表键函数之外使用hsiphash函数,只有在你
129+
能完全能确定输出永远不会从内核传输出去的情况下才能使用,
130+
作为缓解哈希表泛洪拒绝服务攻击的一种手段,它仅在某些情况
131+
下比jhash好用。
132+
133+
在64位的内核中,hsiphash函数实际上实现的是SipHash-1-3,这是一
134+
种减少轮数的SipHash变形,而不是HalfSipHash-1-3。这是因为在64位
135+
代码中SipHash-1-3的性能与HalfSipHash-1-3相当,甚至可能更快,请
136+
注意,这并不意味这在64位的内核中,hsihpash函数与siphash函数相
137+
同,也不意味着他们是安全的;hsihash函数仍然使用一种不太安全的
138+
减少轮数的算法,并将输出截断为32位。
139+
140+
生成哈希密钥
141+
============
142+
143+
密钥应始终来源于加密安全的随机数生成,要么使用get random bytes
144+
要么使用get random once::
145+
146+
hsiphash_key_t key;
147+
get_random_bytes(&key, sizeof(key));
148+
149+
如果你的钥匙来源不是这两个,那么你的做法是错的。
150+
151+
使用哈希函数
152+
============
153+
154+
这个函数有两种变体,一个是接受整数列表,另一种是接受缓冲区::
155+
156+
u32 hsiphash(const void *data, size_t len, const hsiphash_key_t *key);
157+
158+
和::
159+
160+
u32 hsiphash_1u32(u32, const hsiphash_key_t *key);
161+
u32 hsiphash_2u32(u32, u32, const hsiphash_key_t *key);
162+
u32 hsiphash_3u32(u32, u32, u32, const hsiphash_key_t *key);
163+
u32 hsiphash_4u32(u32, u32, u32, u32, const hsiphash_key_t *key);
164+
165+
如果向一个通用的hsiphash函数传递一个恒定长度的常量,他将在编译
166+
的时候将常量折叠,并自动选择一个优化后的函数。
167+
168+
哈希表键函数的用法
169+
==================
170+
171+
::
172+
173+
struct some_hashtable {
174+
DECLARE_HASHTABLE(hashtable, 8);
175+
hsiphash_key_t key;
176+
};
177+
178+
void init_hashtable(struct some_hashtable *table)
179+
{
180+
get_random_bytes(&table->key, sizeof(table->key));
181+
}
182+
183+
static inline hlist_head *some_hashtable_bucket(struct some_hashtable *table, struct interesting_input *input)
184+
{
185+
return &table->hashtable[hsiphash(input, sizeof(*input), &table->key) & (HASH_SIZE(table->hashtable) - 1)];
186+
}
187+
188+
然后,你可以像往常一样对返回的哈希存储桶进行迭代。
189+
190+
性能
191+
====
192+
193+
hsiphash()大约比jhash()慢三倍,这是因为有许多替换,不过这些都不是问题,
194+
因为哈希表查找不是瓶颈。而且,这些牺牲是为了hsiphash()的安全性和DoS抗
195+
性,这是值得的。

0 commit comments

Comments
 (0)