github.com/binbinly/pkg@v0.0.11-0.20240321014439-f4fbf666eb0f/util/xcrypto/des.go (about)

     1  package xcrypto
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/aes"
     6  	"crypto/cipher"
     7  	"crypto/des"
     8  	"errors"
     9  	"io"
    10  )
    11  
    12  // DesCBCEncrypt 加密
    13  func DesCBCEncrypt(originText, key, iv []byte) ([]byte, error) {
    14  
    15  	block, err := des.NewCipher(key)
    16  	if err != nil {
    17  		return nil, err
    18  	}
    19  
    20  	// 返回加密字节块的大小
    21  	blockSize := block.BlockSize()
    22  
    23  	// PKCS5填充需加密内容
    24  	originText = pKCS5Padding(originText, blockSize)
    25  
    26  	// 返回一个密码分组链接模式的、底层用Block加密的cipher.BlockMode,初始向量iv的长度必须等于Block的块尺寸(Block块尺寸等于密钥尺寸)
    27  	blockMode := cipher.NewCBCEncrypter(block, iv)
    28  
    29  	// 根据 需加密内容[]byte长度,初始化一个新的byte数组,返回byte数组内存地址
    30  	cipherText := make([]byte, len(originText))
    31  
    32  	// 加密或解密连续的数据块,将加密内容存储到dst中,src需加密内容的长度必须是块大小的整数倍,src和dst可指向同一内存地址
    33  	blockMode.CryptBlocks(cipherText, originText)
    34  
    35  	return cipherText, nil
    36  }
    37  
    38  // DesCBCDecrypt 解密
    39  func DesCBCDecrypt(cipherText, key, iv []byte) ([]byte, error) {
    40  
    41  	block, err := des.NewCipher(key)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	// 返回一个密码分组链接模式的、底层用b解密的cipher.BlockMode,初始向量iv必须和加密时使用的iv相同
    47  	blockMode := cipher.NewCBCDecrypter(block, iv)
    48  
    49  	// 根据 密文[]byte长度,初始化一个新的byte数组,返回byte数组内存地址
    50  	originText := make([]byte, len(cipherText))
    51  
    52  	// 加密或解密连续的数据块,将解密内容存储到dst中,src需加密内容的长度必须是块大小的整数倍,src和dst可指向同一内存地址
    53  	blockMode.CryptBlocks(originText, cipherText)
    54  
    55  	// PKCS5反填充解密内容
    56  	originText = pKCS5UnPadding(originText)
    57  	return originText, nil
    58  }
    59  
    60  // DesCFBEncrypt 加密
    61  func DesCFBEncrypt(originText, key, iv []byte) ([]byte, error) {
    62  
    63  	block, err := des.NewCipher(key)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	// 根据 需加密内容[]byte长度,初始化一个新的byte数组,返回byte数组内存地址
    69  	cipherText := make([]byte, aes.BlockSize+len(originText))
    70  
    71  	// 返回一个密码反馈模式的、底层用block加密的cipher.Stream,初始向量iv的长度必须等于block的块尺寸
    72  	stream := cipher.NewCFBEncrypter(block, iv)
    73  
    74  	// 从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
    75  	// cipherText[:aes.BlockSize]为iv值,所以只写入cipherText后面部分
    76  	stream.XORKeyStream(cipherText[aes.BlockSize:], originText)
    77  
    78  	return cipherText, nil
    79  }
    80  
    81  // DesCFBDecrypt 解密
    82  func DesCFBDecrypt(cipherText, key, iv []byte) ([]byte, error) {
    83  
    84  	block, err := des.NewCipher(key)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  
    89  	if len(cipherText) < aes.BlockSize {
    90  		return nil, errors.New("cipherText too short")
    91  	}
    92  
    93  	// 只使用cipherText除去iv部分
    94  	cipherText = cipherText[aes.BlockSize:]
    95  
    96  	// 返回一个密码反馈模式的、底层用block解密的cipher.Stream,初始向量iv必须和加密时使用的iv相同
    97  	stream := cipher.NewCFBDecrypter(block, iv)
    98  
    99  	// 从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
   100  	stream.XORKeyStream(cipherText, cipherText)
   101  
   102  	return cipherText, nil
   103  }
   104  
   105  // DesCTREncrypt 加密
   106  func DesCTREncrypt(originText, key, iv []byte) ([]byte, error) {
   107  
   108  	block, err := des.NewCipher(key)
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	// 根据 需加密内容[]byte长度,初始化一个新的byte数组,返回byte数组内存地址
   114  	cipherText := make([]byte, aes.BlockSize+len(originText))
   115  
   116  	// 返回一个计数器模式的、底层采用block生成key流的cipher.Stream,初始向量iv的长度必须等于block的块尺寸
   117  	stream := cipher.NewCTR(block, iv)
   118  
   119  	// 从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
   120  	// cipherText[:aes.BlockSize]为iv值,所以只写入cipherText后面部分
   121  	stream.XORKeyStream(cipherText[aes.BlockSize:], originText)
   122  
   123  	return cipherText, nil
   124  }
   125  
   126  // DesCTRDecrypt 解密
   127  func DesCTRDecrypt(cipherText, key, iv []byte) ([]byte, error) {
   128  
   129  	block, err := des.NewCipher(key)
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  
   134  	// 只使用cipherText除去iv部分
   135  	cipherText = cipherText[aes.BlockSize:]
   136  
   137  	// 返回一个计数器模式的、底层采用block生成key流的cipher.Stream,初始向量iv的长度必须等于block的块尺寸
   138  	stream := cipher.NewCTR(block, iv)
   139  
   140  	// 从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
   141  	stream.XORKeyStream(cipherText, cipherText)
   142  
   143  	return cipherText, nil
   144  }
   145  
   146  // DesOFBEncrypt 加密
   147  func DesOFBEncrypt(originText, key, iv []byte) ([]byte, error) {
   148  
   149  	block, err := des.NewCipher(key)
   150  	if err != nil {
   151  		return nil, err
   152  	}
   153  
   154  	// 根据 需加密内容[]byte长度,初始化一个新的byte数组,返回byte数组内存地址
   155  	cipherText := make([]byte, aes.BlockSize+len(originText))
   156  
   157  	// 返回一个输出反馈模式的、底层采用b生成key流的cipher.Stream,初始向量iv的长度必须等于b的块尺寸
   158  	stream := cipher.NewOFB(block, iv)
   159  
   160  	// 从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
   161  	// cipherText[:aes.BlockSize]为iv值,所以只写入cipherText后面部分
   162  	stream.XORKeyStream(cipherText[aes.BlockSize:], originText)
   163  
   164  	return cipherText, nil
   165  }
   166  
   167  // DesOFBDecrypt 解密
   168  func DesOFBDecrypt(cipherText, key, iv []byte) ([]byte, error) {
   169  
   170  	block, err := des.NewCipher(key)
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  
   175  	// 只使用cipherText除去iv部分
   176  	cipherText = cipherText[aes.BlockSize:]
   177  
   178  	// 返回一个输出反馈模式的、底层采用b生成key流的cipher.Stream,初始向量iv的长度必须等于b的块尺寸
   179  	stream := cipher.NewOFB(block, iv)
   180  
   181  	// 从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
   182  	stream.XORKeyStream(cipherText, cipherText)
   183  
   184  	return cipherText, nil
   185  }
   186  
   187  // DesOFBEncryptStreamReader 加密
   188  func DesOFBEncryptStreamReader(originText, key, iv []byte) ([]byte, error) {
   189  
   190  	block, err := des.NewCipher(key)
   191  	if err != nil {
   192  		return nil, err
   193  	}
   194  
   195  	// 返回一个输出反馈模式的、底层采用b生成key流的cipher.Stream,初始向量iv的长度必须等于b的块尺寸
   196  	stream := cipher.NewOFB(block, iv)
   197  
   198  	// 初始化cipher.StreamReader。将一个cipher.Stream与一个io.Reader关联起来,Read方法会调用XORKeyStream方法来处理获取的所有切片
   199  	reader := &cipher.StreamReader{
   200  		S: stream,
   201  		R: bytes.NewReader(originText),
   202  	}
   203  
   204  	return io.ReadAll(reader)
   205  }
   206  
   207  // DesOFBDecryptStreamWriter 解密
   208  func DesOFBDecryptStreamWriter(cipherText, key, iv []byte) ([]byte, error) {
   209  
   210  	block, err := des.NewCipher(key)
   211  	if err != nil {
   212  		return nil, err
   213  	}
   214  
   215  	// 返回一个输出反馈模式的、底层采用b生成key流的cipher.Stream,初始向量iv的长度必须等于b的块尺寸
   216  	stream := cipher.NewOFB(block, iv)
   217  
   218  	// 声明buffer
   219  	var originText bytes.Buffer
   220  
   221  	// 初始化cipher.StreamWriter。将一个cipher.Stream与一个io.Writer接口关联起来,Write方法会调用XORKeyStream方法来处理提供的所有切片
   222  	// 如果Write方法返回的n小于提供的切片的长度,则表示StreamWriter不同步,必须丢弃。StreamWriter没有内建的缓存,不需要调用Close方法去清空缓存
   223  	writer := &cipher.StreamWriter{
   224  		S: stream,
   225  		W: &originText,
   226  	}
   227  
   228  	// 把reader内容拷贝到writer, writer会调用write方法写入内容
   229  	if _, err = io.Copy(writer, bytes.NewReader(cipherText)); err != nil {
   230  		return nil, err
   231  	}
   232  
   233  	return originText.Bytes(), nil
   234  }