我从golang中的https://stackoverflow.com/questions/24072026/golang-aes-ecb-encryption/71614065?noredirect=1#comment126568172_71614065找到了代码片段,用于解密ECB中的AES-128数据(注意块大小为 16 字节):
package main
import (
"crypto/aes"
)
func DecryptAes128Ecb(data, key []byte) []byte {
cipher, _ := aes.NewCipher([]byte(key))
decrypted := make([]byte, len(data))
size := 16
for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
cipher.Decrypt(decrypted[bs:be], data[bs:be])
}
return decrypted
}
我尝试在网上搜索,但无法获得完整的代码并理解它。
首先,请记住 ECB 不安全,不得用于真正的加密。话虽如此,以下是代码逐行执行的操作:
cipher, _ := aes.NewCipher([]byte(key))
这将返回一个新对象,其中具有使用给定密钥执行 AES 加密/解密的方法。
decrypted := make([]byte, len(data))
这会分配空间来保存解密结果。长度与输入的长度相同。
size := 16
这是 AES 密码的块大小(以字节为单位)。我们也可以在这里写
size := cipher.BlockSize()
。输入的长度必须是16字节的倍数。
for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size { ... }
这会迭代输入中的 16 字节块。第一个块有开始
bs = 0
和结束 be = size
,我们只需重复将 16 添加到 bs
和 be
即可获得所有其他块。
cipher.Decrypt(decrypted[bs:be], data[bs:be])
这使用我们在开始时创建的
cipher
对象来解密单个块。输入是 data[bs:be]
,输出存储在 decrypted[bs:be]
中。循环完成后,切片decrypted
包含解密的明文。
那么如何进行ECB加密的代码答案如下:
import (
"crypto/aes"
)
func normalizePhoneNumber(phoneNumber string) ([]byte){
// Convert phone number into a standard form such as:
// +19123457890
// then with normalBytes
block := make([]byte, 16)
copy(block, normalBytes)
return block
}
func getKey()([]byte){
// TODO implement get 256 bit key
}
// People say ECB is insecure but sometimes it's the best option,
// Certainly for de-anonymizing phone numbers it's better than hashing
func Encode(phoneNumber string) (enc []byte, err error) {
enc = normalizePhoneNumber(phoneNumber)
keyBytes := getKey()
encrypted := make([]byte, 16)
cipher, err := aes.NewCipher(keyBytes)
if err != nil{
return
}
// since enc overlaps enc entirely this does
// an in place encryption.
cipher.encrypt(enc, enc)
return
}
我会将意见留给其他人,但恕我直言,有时 ECB 只是门票,特别是如果您正在保存一个需要保留平等属性的电话号码数据库,而 ECB 是理想的选择,并且如果该数据库由电话号码作为密钥,则黑客将发现去匿名化比拥有哈希电话号码列表要困难得多。至少不会,除非他们获得加密密钥。