我想知道我应该如何在我的代码中实现一次性的pad加密。
我现在使用16字节的页面,以及页面中的Golang实现:https://github.com/ryanuber/go-otp/blob/master/otp.go (第83行是Encrypt()方法)。
但是,有时我需要加密的数据(并不总是)大于16字节。
// Page must be at least as long as plain text
if len(page) < len(payload) {
return nil, fmt.Errorf("otp: insufficient page size")
}
result := make([]byte, len(payload))
for i := 0; i < len(payload); i++ {
plainText := int(payload[i])
secretKey := int(page[i]) // ln 95
cipherText := (plainText + secretKey) % 255
result[i] = byte(cipherText)
}我所做的是注释掉页面长度检查,所以加密现在忽略长度问题;在索引page时使用模数(第95行):
secretKey := int(page[i % len(page)])所以,如果我加密10兆字节的数据缓冲区,它仍然安全吗?如果不是,为什么?
发布于 2018-04-07 17:56:40
这是个非常糟糕的主意。首先,这不是一个一次性的数据垫,因为您使用相同的pad加密多个数据块。这与发送多条单独加密的消息完全相同。
针对此方案有多个琐碎的攻击:
xor,并恢复您的便笺的字节。然后,它们可以移动到重复使用pad字节的每个位置(例如,+/- len(page)),对pad字节进行xor,并恢复更多明文。发布于 2018-04-07 17:50:40
如果你不止一次地使用一个字节,它就不再是一个计时盘了。
如果您的键重复,结果可能会被破坏,因为底层数据可能包含冗余。在谷歌上搜索诸如“打破重复键xor”之类的内容,会让你开始学习技术。
https://security.stackexchange.com/questions/183181
复制相似问题