在Go语言中安全比较字符串

20

Go语言是否内置了一种执行常数时间字符串比较的方法?

当我需要在Ruby中实现此功能时,我使用了 Devise.secure_compare 方法。


2
secure_compare 不是一个常量时间方法,它调用了 each_byte,该方法迭代字符串中的每个字节。http://apidock.com/ruby/String/each_byte - Seth Hoenig
2
“常数时间”和“安全”是非常不同的目标;请明确您想要什么。 - Vitruvie
5
这段话是关于时序攻击的。常量时间比较与时间复杂度无关,只是指比较函数在发现差异时不会提前返回(这将泄漏输入之间的差异信息)。比较函数只与输入的长度有关,而与内容无关。 - nemo
1个回答

37

不适用于字符串,而是适用于[]byte。请参阅crypto/subtle,特别是ConstantTimeCompare

func ConstantTimeCompare(x, y []byte) int

如果两个等长的切片x和y包含相同的内容,则ConstantTimeCompare返回1。计算时间是切片长度的函数,与内容无关。

正如您可能知道的那样,您可以轻松地将字符串转换为字节切片:

var x []byte = []byte("someString")

6
由于subtle.ConstantTimeCompare需要“两个等长的片段”,因此使用subtle.ConstantTimeEq比较切片的长度也很重要,因为它在其他情况下具有一些“微妙”的行为。例如:http://play.golang.org/p/Xga-wsZvhT - Intermernet
3
在上面的示例中,行为似乎是正确的。长度不相等的切片不相等。 - stevvooe
1
@MichaelBaldry 当数组长度不相等时,该函数以常数时间返回false,并在数组长度相等时以(另一个)常数时间返回true。因此,该函数不会通过计时泄露有关内容正确性的信息。 - nemo
4
“[]byte([of a string])” 虽然是一种将字符串转换为字节数组的非常量时间操作,因为这会复制字符串,看起来会泄露预期字符串的长度。 - John Gibb
1
@JohnGibb 是的,如果您在与比较相同的请求中进行转换,则会泄漏信息。如果您将转换后的字节数组保存在内存中,则不会泄漏信息。 - nemo
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接