83 lines
2.3 KiB
Markdown
Raw Normal View History

2021-11-21 15:25:11 +00:00
# PCSK#7 填充读写流
直接使用分块加密,往往需要手动完成填充和去填充的过程。流程较为固定,但是比较繁琐,对于文件和流的处理,不是很友好。
PKCS#7填充和去除填充
- `padding.PKCS7PaddingReader` 写入结束是添加填充
- `padding.PKCS7PaddingWriter` 读取时去除填充
封装的填充模式加密:
- `padding.P7BlockEnc`
- `padding.P7BlockDecrypt`
以上方法简化了,对文件和流类型的加密解密过程。
## 带填充的模式加密和解密
> 流:实现了 `io.Writer`、`io.Reader`接口的类型。
流的SM4分块CBC模式加密
```go
func main() {
src := bytes.Repeat([]byte{7}, 16)
srcIn := bytes.NewBuffer(src)
encOut := bytes.NewBuffer(make([]byte, 0, 1024))
key := make([]byte, 16)
iv := make([]byte, 16)
_, _ = rand.Read(key)
_, _ = rand.Read(iv)
fmt.Printf("key: %02X\n", key)
fmt.Printf("iv : %02X\n", iv)
block, err := sm4.NewCipher(key)
if err != nil {
panic(err)
}
encrypter := cipher.NewCBCEncrypter(block, iv)
// P7填充的CBC加密
err = padding.P7BlockEnc(encrypter, srcIn, encOut)
if err != nil {
panic(err)
}
fmt.Printf("原文: %02X\n", src)
fmt.Printf("加密: %02X\n", encOut.Bytes())
}
```
流的SM4分块CBC模式解密
```go
func main() {
/**
key: 4C9CA3D17263F6F558D65ADB561465BD
iv : 221908D1C4BD730BEB011319D1368E49
原文: 07070707070707070707070707070707
加密: 310CA2472DCE15CCC58E1BE69B876002F443556CCFB86B1BA0341B6BFBED4C1A
*/
encOut := bytes.NewBuffer(make([]byte, 0, 1024))
key,_ := hex.DecodeString("4C9CA3D17263F6F558D65ADB561465BD")
iv,_ := hex.DecodeString("221908D1C4BD730BEB011319D1368E49")
block, err := sm4.NewCipher(key)
if err != nil {
panic(err)
}
ciphertext, _ := hex.DecodeString("310CA2472DCE15CCC58E1BE69B876002F443556CCFB86B1BA0341B6BFBED4C1A")
cipherReader := bytes.NewReader(ciphertext)
decrypter := cipher.NewCBCDecrypter(block, iv)
decOut := bytes.NewBuffer(make([]byte, 0, 1024))
err = padding.P7BlockDecrypt(decrypter, ciphertext, decOut)
if err != nil {
panic(err)
}
fmt.Printf("解密: %02X\n", decOut.Bytes())
}
```
## PKCS#7填充
见测试用例: [pkcs7_padding_io_test.go](./pkcs7_padding_io_test.go)