github.com/tickstep/library-go@v0.1.1/crypto/aes_full.go (about)

     1  package crypto
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/aes"
     6  	"crypto/cipher"
     7  	cryptorand "crypto/rand"
     8  	"fmt"
     9  	"github.com/tickstep/library-go/crypto/ecb"
    10  	"io"
    11  )
    12  
    13  // AesMode AES 工作模式
    14  type AesMode int
    15  
    16  const (
    17  	// AesECB ecb 模式
    18  	AesECB AesMode = iota
    19  	// AesCBC cbc 模式
    20  	AesCBC
    21  	// AesCTR ctr 模式
    22  	AesCTR
    23  	// AesCFB cfb 模式
    24  	AesCFB
    25  	// AesOFB ofb 模式
    26  	AesOFB
    27  )
    28  
    29  // Aes128ECBEncrypt aes-128-ecb 加密
    30  func Aes128ECBEncrypt(key [16]byte, plaintext []byte) (ciphertext []byte, err error) {
    31  	return aesECBEnc(key[:], plaintext)
    32  }
    33  
    34  // Aes128ECBDecrypt aes-128-ecb 解密
    35  func Aes128ECBDecrypt(key [16]byte, ciphertext []byte) (plaintext []byte, err error) {
    36  	return aesECBDec(key[:], ciphertext)
    37  }
    38  
    39  // Aes192ECBEncrypt aes-192-ecb 加密
    40  func Aes192ECBEncrypt(key [24]byte, plaintext []byte) (ciphertext []byte, err error) {
    41  	return aesECBEnc(key[:], plaintext)
    42  }
    43  
    44  // Aes192ECBDecrypt aes-192-ecb 解密
    45  func Aes192ECBDecrypt(key [24]byte, ciphertext []byte) (plaintext []byte, err error) {
    46  	return aesECBDec(key[:], ciphertext)
    47  }
    48  
    49  // Aes256ECBEncrypt aes-256-ecb 加密
    50  func Aes256ECBEncrypt(key [32]byte, plaintext []byte) (ciphertext []byte, err error) {
    51  	return aesECBEnc(key[:], plaintext)
    52  }
    53  
    54  // Aes256ECBDecrypt aes-256-ecb 解密
    55  func Aes256ECBDecrypt(key [32]byte, ciphertext []byte) (plaintext []byte, err error) {
    56  	return aesECBDec(key[:], ciphertext)
    57  }
    58  
    59  // Aes128CBCEncrypt aes-128-cbc 加密
    60  func Aes128CBCEncrypt(key [16]byte, plaintext []byte) (ciphertext []byte, err error) {
    61  	return aesCBCEnc(key[:], plaintext)
    62  }
    63  
    64  // Aes128CBCDecrypt aes-128-cbc 解密
    65  func Aes128CBCDecrypt(key [16]byte, ciphertext []byte) (plaintext []byte, err error) {
    66  	return aesCBCDec(key[:], ciphertext)
    67  }
    68  
    69  // Aes192CBCEncrypt aes-192-cbc 加密
    70  func Aes192CBCEncrypt(key [24]byte, plaintext []byte) (ciphertext []byte, err error) {
    71  	return aesCBCEnc(key[:], plaintext)
    72  }
    73  
    74  // Aes192CBCDecrypt aes-192-cbc 解密
    75  func Aes192CBCDecrypt(key [24]byte, ciphertext []byte) (plaintext []byte, err error) {
    76  	return aesCBCDec(key[:], ciphertext)
    77  }
    78  
    79  // Aes256CBCEncrypt aes-256-cbc 加密
    80  func Aes256CBCEncrypt(key [32]byte, plaintext []byte) (ciphertext []byte, err error) {
    81  	return aesCBCEnc(key[:], plaintext)
    82  }
    83  
    84  // Aes256CBCDecrypt aes-256-cbc 解密
    85  func Aes256CBCDecrypt(key [32]byte, ciphertext []byte) (plaintext []byte, err error) {
    86  	return aesCBCDec(key[:], ciphertext)
    87  }
    88  
    89  // Aes128CTREncrypt aes-128-ctr 加密
    90  func Aes128CTREncrypt(key [16]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
    91  	return aesCTREnc(key[:], plainReader)
    92  }
    93  
    94  // Aes128CTRDecrypt aes-128-ctr 解密
    95  func Aes128CTRDecrypt(key [16]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
    96  	return aesCTRDec(key[:], cipherReader)
    97  }
    98  
    99  // Aes192CTREncrypt aes-192-ctr 加密
   100  func Aes192CTREncrypt(key [24]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   101  	return aesCTREnc(key[:], plainReader)
   102  }
   103  
   104  // Aes192CTRDecrypt aes-192-ctr 解密
   105  func Aes192CTRDecrypt(key [24]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   106  	return aesCTRDec(key[:], cipherReader)
   107  }
   108  
   109  // Aes256CTREncrypt aes-256-ctr 加密
   110  func Aes256CTREncrypt(key [32]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   111  	return aesCTREnc(key[:], plainReader)
   112  }
   113  
   114  // Aes256CTRDecrypt aes-256-ctr 解密
   115  func Aes256CTRDecrypt(key [32]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   116  	return aesCTRDec(key[:], cipherReader)
   117  }
   118  
   119  // Aes128CFBEncrypt aes-128-cfb 加密
   120  func Aes128CFBEncrypt(key [16]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   121  	return aesCFBEnc(key[:], plainReader)
   122  }
   123  
   124  // Aes128CFBDecrypt aes-128-cfb 解密
   125  func Aes128CFBDecrypt(key [16]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   126  	return aesCFBDec(key[:], cipherReader)
   127  }
   128  
   129  // Aes192CFBEncrypt aes-192-cfb 加密
   130  func Aes192CFBEncrypt(key [24]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   131  	return aesCFBEnc(key[:], plainReader)
   132  }
   133  
   134  // Aes192CFBDecrypt aes-192-cfb 解密
   135  func Aes192CFBDecrypt(key [24]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   136  	return aesCFBDec(key[:], cipherReader)
   137  }
   138  
   139  // Aes256CFBEncrypt aes-256-cfb 加密
   140  func Aes256CFBEncrypt(key [32]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   141  	return aesCFBEnc(key[:], plainReader)
   142  }
   143  
   144  // Aes256CFBDecrypt aes-256-cfb 解密
   145  func Aes256CFBDecrypt(key [32]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   146  	return aesCFBDec(key[:], cipherReader)
   147  }
   148  
   149  // Aes128OFBEncrypt aes-128-ofb 加密
   150  func Aes128OFBEncrypt(key [16]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   151  	return aesOFBEnc(key[:], plainReader)
   152  }
   153  
   154  // Aes128OFBDecrypt aes-128-ofb 解密
   155  func Aes128OFBDecrypt(key [16]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   156  	return aesOFBDec(key[:], cipherReader)
   157  }
   158  
   159  // Aes192OFBEncrypt aes-192-ofb 加密
   160  func Aes192OFBEncrypt(key [24]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   161  	return aesOFBEnc(key[:], plainReader)
   162  }
   163  
   164  // Aes192OFBDecrypt aes-192-ofb 解密
   165  func Aes192OFBDecrypt(key [24]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   166  	return aesOFBDec(key[:], cipherReader)
   167  }
   168  
   169  // Aes256OFBEncrypt aes-256-ofb 加密
   170  func Aes256OFBEncrypt(key [32]byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   171  	return aesOFBEnc(key[:], plainReader)
   172  }
   173  
   174  // Aes256OFBDecrypt aes-256-ofb 解密
   175  func Aes256OFBDecrypt(key [32]byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   176  	return aesOFBDec(key[:], cipherReader)
   177  }
   178  
   179  // Convert16bytes 将 []byte 转为 [16]byte
   180  func Convert16bytes(b []byte) (b16 [16]byte) {
   181  	copy(b16[:], b)
   182  	return
   183  }
   184  
   185  // Convert24bytes 将 []byte 转为 [24]byte
   186  func Convert24bytes(b []byte) (b24 [24]byte) {
   187  	copy(b24[:], b)
   188  	return
   189  }
   190  
   191  // Convert32bytes 将 []byte 转为 [32]byte
   192  func Convert32bytes(b []byte) (b32 [32]byte) {
   193  	copy(b32[:], b)
   194  	return
   195  }
   196  
   197  func aesECBEnc(key []byte, plaintext []byte) (ciphertext []byte, err error) {
   198  	block, err := aes.NewCipher(key) //选择加密算法
   199  	if err != nil {
   200  		return nil, err
   201  	}
   202  
   203  	plaintext = PKCS5Padding(plaintext, block.BlockSize())
   204  
   205  	blockModel := ecb.NewECBEncrypter(block)
   206  
   207  	ciphertext = plaintext
   208  
   209  	blockModel.CryptBlocks(ciphertext, plaintext)
   210  	return ciphertext, nil
   211  }
   212  
   213  func aesECBDec(key []byte, ciphertext []byte) (plaintext []byte, err error) {
   214  	block, err := aes.NewCipher(key)
   215  	if err != nil {
   216  		return nil, err
   217  	}
   218  
   219  	blockModel := ecb.NewECBDecrypter(block)
   220  
   221  	plaintext = ciphertext
   222  	blockModel.CryptBlocks(plaintext, ciphertext)
   223  
   224  	plaintext = PKCS5UnPadding(plaintext)
   225  
   226  	return plaintext, nil
   227  }
   228  
   229  func aesCBCEnc(key []byte, plaintext []byte) (ciphertext []byte, err error) {
   230  	block, err := aes.NewCipher(key) //选择加密算法
   231  	if err != nil {
   232  		return nil, err
   233  	}
   234  
   235  	plaintext = PKCS5Padding(plaintext, block.BlockSize())
   236  
   237  	ciphertext = make([]byte, aes.BlockSize+len(plaintext))
   238  
   239  	iv := ciphertext[:aes.BlockSize]
   240  	_, err = cryptorand.Read(iv[:])
   241  	if err != nil {
   242  		return nil, err
   243  	}
   244  
   245  	blockModel := cipher.NewCBCEncrypter(block, iv[:])
   246  
   247  	blockModel.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
   248  	return ciphertext, nil
   249  }
   250  
   251  func aesCBCDec(key []byte, ciphertext []byte) (plaintext []byte, err error) {
   252  	if len(ciphertext) < aes.BlockSize {
   253  		return nil, fmt.Errorf("ciphertext too short")
   254  	}
   255  
   256  	block, err := aes.NewCipher(key)
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	iv := ciphertext[:aes.BlockSize]
   262  	ciphertext = ciphertext[aes.BlockSize:]
   263  
   264  	// CBC mode always works in whole blocks.
   265  	if len(ciphertext)%aes.BlockSize != 0 {
   266  		return nil, fmt.Errorf("ciphertext is not a multiple of the block size")
   267  	}
   268  
   269  	blockModel := cipher.NewCBCDecrypter(block, iv)
   270  	plaintext = ciphertext
   271  	blockModel.CryptBlocks(plaintext, ciphertext)
   272  
   273  	plaintext = PKCS5UnPadding(plaintext)
   274  	return plaintext, nil
   275  }
   276  
   277  func aesCTREnc(key []byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   278  	return streamEnc(AesCTR, key, plainReader)
   279  }
   280  
   281  func aesCTRDec(key []byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   282  	return streamDec(AesCTR, key, cipherReader)
   283  }
   284  
   285  func aesCFBEnc(key []byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   286  	return streamEnc(AesCFB, key, plainReader)
   287  }
   288  
   289  func aesCFBDec(key []byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   290  	return streamDec(AesCFB, key, cipherReader)
   291  }
   292  
   293  func aesOFBEnc(key []byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   294  	return streamEnc(AesOFB, key, plainReader)
   295  }
   296  
   297  func aesOFBDec(key []byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   298  	return streamDec(AesOFB, key, cipherReader)
   299  }
   300  
   301  func streamEnc(aesMode AesMode, key []byte, plainReader io.Reader) (cipherReader io.Reader, err error) {
   302  	block, err := aes.NewCipher(key)
   303  	if err != nil {
   304  		return nil, err
   305  	}
   306  
   307  	// 随机初始化向量
   308  	var iv [aes.BlockSize]byte
   309  	cryptorand.Read(iv[:])
   310  
   311  	var stream cipher.Stream
   312  	switch aesMode {
   313  	case AesCTR:
   314  		stream = cipher.NewCTR(block, iv[:])
   315  	case AesCFB:
   316  		stream = cipher.NewCFBEncrypter(block, iv[:])
   317  	case AesOFB:
   318  		stream = cipher.NewOFB(block, iv[:])
   319  	default:
   320  		panic("unknown aes mode")
   321  	}
   322  
   323  	reader := &cipher.StreamReader{
   324  		S: stream,
   325  		R: plainReader,
   326  	}
   327  
   328  	return io.MultiReader(bytes.NewReader(iv[:]), reader), nil
   329  }
   330  
   331  func streamDec(aesMode AesMode, key []byte, cipherReader io.Reader) (plainReader io.Reader, err error) {
   332  	block, err := aes.NewCipher(key)
   333  	if err != nil {
   334  		return nil, err
   335  	}
   336  
   337  	var iv [aes.BlockSize]byte
   338  
   339  	// 读取头部向量
   340  	_, err = cipherReader.Read(iv[:])
   341  	if err != nil {
   342  		return
   343  	}
   344  
   345  	var stream cipher.Stream
   346  	switch aesMode {
   347  	case AesCTR:
   348  		stream = cipher.NewCTR(block, iv[:])
   349  	case AesCFB:
   350  		stream = cipher.NewCFBDecrypter(block, iv[:])
   351  	case AesOFB:
   352  		stream = cipher.NewOFB(block, iv[:])
   353  	default:
   354  		panic("unknown aes mode")
   355  	}
   356  
   357  	plainReader = &cipher.StreamReader{
   358  		S: stream,
   359  		R: cipherReader,
   360  	}
   361  	return
   362  }
   363  
   364  // PKCS5Padding PKCS5 Padding
   365  func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
   366  	padding := blockSize - len(ciphertext)%blockSize
   367  	if padding < 0 {
   368  		padding = 0
   369  	}
   370  
   371  	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
   372  	return append(ciphertext, padtext...)
   373  }
   374  
   375  // PKCS5UnPadding PKCS5 UnPadding
   376  func PKCS5UnPadding(plaintext []byte) []byte {
   377  	length := len(plaintext)
   378  	if length <= 0 {
   379  		return nil
   380  	}
   381  
   382  	unpadding := int(plaintext[length-1])
   383  	if length-unpadding < 0 {
   384  		return nil
   385  	}
   386  
   387  	return plaintext[:(length - unpadding)]
   388  }