gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/sm4soft/padding/README.md (about)

     1  # PCSK#7 填充读写流
     2  
     3  直接使用分块加密,往往需要手动完成填充和去填充的过程。流程较为固定,但是比较繁琐,对于文件和流的处理,不是很友好。
     4  
     5  PKCS#7填充和去除填充:
     6  
     7  - `padding.PKCS7PaddingReader` 写入结束是添加填充
     8  - `padding.PKCS7PaddingWriter` 读取时去除填充
     9  
    10  封装的填充模式加密:
    11  
    12  - `padding.P7BlockEnc`
    13  - `padding.P7BlockDecrypt`
    14  
    15  以上方法简化了,对文件和流类型的加密解密过程。
    16  
    17  ## 带填充的模式加密和解密
    18  
    19  > 流:实现了 `io.Writer`、`io.Reader`接口的类型。
    20  
    21  流的SM4分块CBC模式加密:
    22  
    23  ```go
    24  func main() {
    25      src := bytes.Repeat([]byte{7}, 16)
    26      srcIn := bytes.NewBuffer(src)
    27      encOut := bytes.NewBuffer(make([]byte, 0, 1024))
    28  
    29      key := make([]byte, 16)
    30      iv := make([]byte, 16)
    31      _, _ = rand.Read(key)
    32      _, _ = rand.Read(iv)
    33      fmt.Printf("key: %02X\n", key)
    34      fmt.Printf("iv : %02X\n", iv)
    35      block, err := sm4.NewCipher(key)
    36      if err != nil {
    37          panic(err)
    38      }
    39      encrypter := cipher.NewCBCEncrypter(block, iv)
    40      // P7填充的CBC加密
    41      err = padding.P7BlockEnc(encrypter, srcIn, encOut)
    42      if err != nil {
    43          panic(err)
    44      }
    45      fmt.Printf("原文: %02X\n", src)
    46      fmt.Printf("加密: %02X\n", encOut.Bytes())
    47  }
    48  ```
    49  
    50  流的SM4分块CBC模式解密:
    51  
    52  ```go
    53  func main() {
    54      /**
    55  	key: 4C9CA3D17263F6F558D65ADB561465BD
    56  	iv : 221908D1C4BD730BEB011319D1368E49
    57  	原文: 07070707070707070707070707070707
    58  	加密: 310CA2472DCE15CCC58E1BE69B876002F443556CCFB86B1BA0341B6BFBED4C1A
    59       */
    60  	encOut := bytes.NewBuffer(make([]byte, 0, 1024))
    61  	key,_ := hex.DecodeString("4C9CA3D17263F6F558D65ADB561465BD")
    62      iv,_ := hex.DecodeString("221908D1C4BD730BEB011319D1368E49")
    63      block, err := sm4.NewCipher(key)
    64      if err != nil {
    65          panic(err)
    66      }
    67      ciphertext, _ :=  hex.DecodeString("310CA2472DCE15CCC58E1BE69B876002F443556CCFB86B1BA0341B6BFBED4C1A")
    68      cipherReader := bytes.NewReader(ciphertext)
    69      decrypter := cipher.NewCBCDecrypter(block, iv)
    70      decOut := bytes.NewBuffer(make([]byte, 0, 1024))
    71      err = padding.P7BlockDecrypt(decrypter, ciphertext, decOut)
    72      if err != nil {
    73          panic(err)
    74      }
    75      
    76      fmt.Printf("解密: %02X\n", decOut.Bytes())
    77  }
    78  ```
    79  
    80  ## PKCS#7填充
    81  
    82  见测试用例: [pkcs7_padding_io_test.go](./pkcs7_padding_io_test.go)