diff --git a/concurrency/keyed_locker.go b/concurrency/keyed_locker.go index a921228..651619d 100644 --- a/concurrency/keyed_locker.go +++ b/concurrency/keyed_locker.go @@ -2,7 +2,6 @@ // Use of this source code is governed by MIT license // Package concurrency contain some functions to support concurrent programming. eg, goroutine, channel, locker. - package concurrency import ( diff --git a/cryptor/basic.go b/cryptor/basic.go index 2b45f24..7818e81 100644 --- a/cryptor/basic.go +++ b/cryptor/basic.go @@ -6,7 +6,6 @@ package cryptor import ( - "bufio" "crypto/hmac" "crypto/md5" "crypto/sha1" @@ -66,34 +65,37 @@ func Md5ByteWithBase64(data []byte) string { // Md5File return the md5 value of file. func Md5File(filename string) (string, error) { - if fileInfo, err := os.Stat(filename); err != nil { - return "", err - } else if fileInfo.IsDir() { - return "", nil - } - file, err := os.Open(filename) if err != nil { return "", err } defer file.Close() - hash := md5.New() - - chunkSize := 65536 - for buf, reader := make([]byte, chunkSize), bufio.NewReader(file); ; { - n, err := reader.Read(buf) - if err != nil { - if err == io.EOF { - break - } - return "", err - } - hash.Write(buf[:n]) + stat, err := file.Stat() + if err != nil { + return "", err + } + if stat.IsDir() { + return "", nil } - checksum := fmt.Sprintf("%x", hash.Sum(nil)) - return checksum, nil + hash := md5.New() + buf := make([]byte, 65536) // 64KB + + for { + n, err := file.Read(buf) + if err != nil && err != io.EOF { + return "", err + } + if n > 0 { + hash.Write(buf[:n]) + } + if err == io.EOF { + break + } + } + + return fmt.Sprintf("%x", hash.Sum(nil)), nil } // HmacMd5 return the hmac hash of string use md5. diff --git a/cryptor/crypto.go b/cryptor/crypto.go index 9f4f338..1fbf3f8 100644 --- a/cryptor/crypto.go +++ b/cryptor/crypto.go @@ -15,39 +15,40 @@ import ( "crypto/rand" "crypto/rsa" "crypto/sha256" - "crypto/sha512" "crypto/x509" "encoding/pem" - "errors" "io" "os" - "strings" ) // AesEcbEncrypt encrypt data with key use AES ECB algorithm // len(key) should be 16, 24 or 32. // Play: https://go.dev/play/p/jT5irszHx-j func AesEcbEncrypt(data, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } - length := (len(data) + aes.BlockSize) / aes.BlockSize - plain := make([]byte, length*aes.BlockSize) + blockSize := aes.BlockSize + dataLen := len(data) + padding := blockSize - (dataLen % blockSize) + paddedLen := dataLen + padding - copy(plain, data) + paddedData := make([]byte, paddedLen) + copy(paddedData, data) - pad := byte(len(plain) - len(data)) - for i := len(data); i < len(plain); i++ { - plain[i] = pad + for i := dataLen; i < paddedLen; i++ { + paddedData[i] = byte(padding) } - encrypted := make([]byte, len(plain)) - cipher, _ := aes.NewCipher(generateAesKey(key, size)) + cipher, err := aes.NewCipher(generateAesKey(key, len(key))) + if err != nil { + panic("aes: failed to create cipher: " + err.Error()) + } - for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { - cipher.Encrypt(encrypted[bs:be], plain[bs:be]) + encrypted := make([]byte, paddedLen) + for bs := 0; bs < paddedLen; bs += blockSize { + cipher.Encrypt(encrypted[bs:], paddedData[bs:]) } return encrypted @@ -57,77 +58,107 @@ func AesEcbEncrypt(data, key []byte) []byte { // len(key) should be 16, 24 or 32. // Play: https://go.dev/play/p/jT5irszHx-j func AesEcbDecrypt(encrypted, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } - cipher, _ := aes.NewCipher(generateAesKey(key, size)) + + blockSize := aes.BlockSize + if len(encrypted)%blockSize != 0 { + panic("aes: encrypted data length is not a multiple of block size") + } + + cipher, err := aes.NewCipher(generateAesKey(key, len(key))) + if err != nil { + panic("aes: failed to create cipher: " + err.Error()) + } + decrypted := make([]byte, len(encrypted)) - - for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { - cipher.Decrypt(decrypted[bs:be], encrypted[bs:be]) + for i := 0; i < len(encrypted); i += blockSize { + cipher.Decrypt(decrypted[i:], encrypted[i:]) } - trim := 0 - if len(decrypted) > 0 { - trim = len(decrypted) - int(decrypted[len(decrypted)-1]) + if len(decrypted) == 0 { + return nil + } + padding := int(decrypted[len(decrypted)-1]) + if padding == 0 || padding > blockSize { + panic("aes: invalid PKCS#7 padding") + } + for i := len(decrypted) - padding; i < len(decrypted); i++ { + if decrypted[i] != byte(padding) { + panic("aes: invalid PKCS#7 padding content") + } } - return decrypted[:trim] + return decrypted[:len(decrypted)-padding] } // AesCbcEncrypt encrypt data with key use AES CBC algorithm // len(key) should be 16, 24 or 32. // Play: https://go.dev/play/p/IOq_g8_lKZD func AesCbcEncrypt(data, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } - block, _ := aes.NewCipher(key) - data = pkcs7Padding(data, block.BlockSize()) + block, err := aes.NewCipher(key) + if err != nil { + panic("aes: failed to create cipher: " + err.Error()) + } - encrypted := make([]byte, aes.BlockSize+len(data)) - iv := encrypted[:aes.BlockSize] + padding := aes.BlockSize - len(data)%aes.BlockSize + padded := append(data, bytes.Repeat([]byte{byte(padding)}, padding)...) + + iv := make([]byte, aes.BlockSize) if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) + panic("aes: failed to generate IV: " + err.Error()) } + encrypted := make([]byte, len(padded)) mode := cipher.NewCBCEncrypter(block, iv) - mode.CryptBlocks(encrypted[aes.BlockSize:], data) + mode.CryptBlocks(encrypted, padded) - return encrypted + return append(iv, encrypted...) } // AesCbcDecrypt decrypt data with key use AES CBC algorithm // len(key) should be 16, 24 or 32. // Play: https://go.dev/play/p/IOq_g8_lKZD func AesCbcDecrypt(encrypted, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } - block, _ := aes.NewCipher(key) + if len(encrypted) < aes.BlockSize { + panic("aes: ciphertext too short") + } + + if len(encrypted)%aes.BlockSize != 0 { + panic("aes: ciphertext is not a multiple of the block size") + } iv := encrypted[:aes.BlockSize] - encrypted = encrypted[aes.BlockSize:] + ciphertext := encrypted[aes.BlockSize:] + block, err := aes.NewCipher(key) + if err != nil { + panic("aes: failed to create cipher: " + err.Error()) + } + + decrypted := make([]byte, len(ciphertext)) mode := cipher.NewCBCDecrypter(block, iv) - mode.CryptBlocks(encrypted, encrypted) + mode.CryptBlocks(decrypted, ciphertext) - decrypted := pkcs7UnPadding(encrypted) - return decrypted + return pkcs7UnPadding(decrypted) } // AesCtrCrypt encrypt data with key use AES CTR algorithm // len(key) should be 16, 24 or 32. // Play: https://go.dev/play/p/SpaZO0-5Nsp +// deprecated: use AesCtrEncrypt and AesCtrDecrypt instead. func AesCtrCrypt(data, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } block, _ := aes.NewCipher(key) @@ -141,158 +172,214 @@ func AesCtrCrypt(data, key []byte) []byte { return dst } -// AesCfbEncrypt encrypt data with key use AES CFB algorithm +// AesCtrEncrypt encrypt data with key use AES CTR algorithm // len(key) should be 16, 24 or 32. -// Play: https://go.dev/play/p/tfkF10B13kH -func AesCfbEncrypt(data, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") +// Play: todo +func AesCtrEncrypt(data, key []byte) []byte { + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } block, err := aes.NewCipher(key) if err != nil { - panic(err) + panic("aes: failed to create cipher: " + err.Error()) } - encrypted := make([]byte, aes.BlockSize+len(data)) - iv := encrypted[:aes.BlockSize] - + iv := make([]byte, aes.BlockSize) if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) + panic("aes: failed to generate IV: " + err.Error()) } - stream := cipher.NewCFBEncrypter(block, iv) - stream.XORKeyStream(encrypted[aes.BlockSize:], data) + stream := cipher.NewCTR(block, iv) + ciphertext := make([]byte, len(data)) + stream.XORKeyStream(ciphertext, data) - return encrypted + return append(iv, ciphertext...) +} + +// AesCtrDecrypt decrypt data with key use AES CTR algorithm +// len(key) should be 16, 24 or 32. +// Play: todo +func AesCtrDecrypt(encrypted, key []byte) []byte { + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") + } + if len(encrypted) < aes.BlockSize { + panic("aes: invalid ciphertext length") + } + + iv := encrypted[:aes.BlockSize] + ciphertext := encrypted[aes.BlockSize:] + + block, err := aes.NewCipher(key) + if err != nil { + panic("aes: failed to create cipher: " + err.Error()) + } + + stream := cipher.NewCTR(block, iv) + plaintext := make([]byte, len(ciphertext)) + stream.XORKeyStream(plaintext, ciphertext) + + return plaintext +} + +// AesCfbEncrypt encrypt data with key use AES CFB algorithm +// len(key) should be 16, 24 or 32. +// Play: https://go.dev/play/p/tfkF10B13kH +func AesCfbEncrypt(data, key []byte) []byte { + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") + } + + block, err := aes.NewCipher(key) + if err != nil { + panic("aes: failed to create cipher: " + err.Error()) + } + + iv := make([]byte, aes.BlockSize) + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + panic("aes: failed to generate IV: " + err.Error()) + } + + ciphertext := make([]byte, len(data)) + stream := cipher.NewCFBEncrypter(block, iv) + stream.XORKeyStream(ciphertext, data) + + return append(iv, ciphertext...) } // AesCfbDecrypt decrypt data with key use AES CFB algorithm // len(encrypted) should be great than 16, len(key) should be 16, 24 or 32. // Play: https://go.dev/play/p/tfkF10B13kH func AesCfbDecrypt(encrypted, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } if len(encrypted) < aes.BlockSize { - panic("encrypted data is too short") + panic("aes: encrypted data too short") } - block, _ := aes.NewCipher(key) iv := encrypted[:aes.BlockSize] - encrypted = encrypted[aes.BlockSize:] + ciphertext := encrypted[aes.BlockSize:] + block, err := aes.NewCipher(key) + if err != nil { + panic("aes: failed to create cipher: " + err.Error()) + } + + plaintext := make([]byte, len(ciphertext)) stream := cipher.NewCFBDecrypter(block, iv) + stream.XORKeyStream(plaintext, ciphertext) - stream.XORKeyStream(encrypted, encrypted) - - return encrypted + return plaintext } // AesOfbEncrypt encrypt data with key use AES OFB algorithm // len(key) should be 16, 24 or 32. // Play: https://go.dev/play/p/VtHxtkUj-3F func AesOfbEncrypt(data, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } block, err := aes.NewCipher(key) if err != nil { - panic(err) + panic("aes: failed to create cipher: " + err.Error()) } - data = pkcs7Padding(data, aes.BlockSize) - encrypted := make([]byte, aes.BlockSize+len(data)) - iv := encrypted[:aes.BlockSize] + iv := make([]byte, aes.BlockSize) if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) + panic("aes: failed to generate IV: " + err.Error()) } + ciphertext := make([]byte, len(data)) stream := cipher.NewOFB(block, iv) - stream.XORKeyStream(encrypted[aes.BlockSize:], data) + stream.XORKeyStream(ciphertext, data) - return encrypted + return append(iv, ciphertext...) } // AesOfbDecrypt decrypt data with key use AES OFB algorithm // len(key) should be 16, 24 or 32. // Play: https://go.dev/play/p/VtHxtkUj-3F func AesOfbDecrypt(data, key []byte) []byte { - size := len(key) - if size != 16 && size != 24 && size != 32 { - panic("key length shoud be 16 or 24 or 32") + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") } - block, err := aes.NewCipher(key) - if err != nil { - panic(err) + if len(data) < aes.BlockSize { + panic("aes: encrypted data too short") } iv := data[:aes.BlockSize] - data = data[aes.BlockSize:] - if len(data)%aes.BlockSize != 0 { - return nil + ciphertext := data[aes.BlockSize:] + + block, err := aes.NewCipher(key) + if err != nil { + panic("aes: failed to create cipher: " + err.Error()) } - decrypted := make([]byte, len(data)) - mode := cipher.NewOFB(block, iv) - mode.XORKeyStream(decrypted, data) + plaintext := make([]byte, len(ciphertext)) + stream := cipher.NewOFB(block, iv) + stream.XORKeyStream(plaintext, ciphertext) - decrypted = pkcs7UnPadding(decrypted) - - return decrypted + return plaintext } // AesGcmEncrypt encrypt data with key use AES GCM algorithm // Play: https://go.dev/play/p/rUt0-DmsPCs func AesGcmEncrypt(data, key []byte) []byte { + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") + } + block, err := aes.NewCipher(key) if err != nil { - panic(err) + panic("aes: failed to create cipher: " + err.Error()) } gcm, err := cipher.NewGCM(block) if err != nil { - panic(err) + panic("aes: failed to create GCM: " + err.Error()) } nonce := make([]byte, gcm.NonceSize()) - if _, err = io.ReadFull(rand.Reader, nonce); err != nil { - panic(err) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + panic("aes: failed to generate nonce: " + err.Error()) } - ciphertext := gcm.Seal(nonce, nonce, data, nil) + ciphertext := gcm.Seal(nil, nonce, data, nil) - return ciphertext + return append(nonce, ciphertext...) } // AesGcmDecrypt decrypt data with key use AES GCM algorithm // Play: https://go.dev/play/p/rUt0-DmsPCs func AesGcmDecrypt(data, key []byte) []byte { + if !isAesKeyLengthValid(len(key)) { + panic("aes: invalid key length (must be 16, 24, or 32 bytes)") + } + block, err := aes.NewCipher(key) if err != nil { - panic(err) + panic("aes: failed to create cipher: " + err.Error()) } gcm, err := cipher.NewGCM(block) if err != nil { - panic(err) + panic("aes: failed to create GCM: " + err.Error()) } nonceSize := gcm.NonceSize() if len(data) < nonceSize { - panic("ciphertext too short") + panic("aes: ciphertext too short") } nonce, ciphertext := data[:nonceSize], data[nonceSize:] plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) if err != nil { - panic(err) + panic("aes: decryption failed: " + err.Error()) } return plaintext @@ -302,20 +389,17 @@ func AesGcmDecrypt(data, key []byte) []byte { // len(key) should be 8. // Play: https://go.dev/play/p/8qivmPeZy4P func DesEcbEncrypt(data, key []byte) []byte { - length := (len(data) + des.BlockSize) / des.BlockSize - plain := make([]byte, length*des.BlockSize) - copy(plain, data) - - pad := byte(len(plain) - len(data)) - for i := len(data); i < len(plain); i++ { - plain[i] = pad + cipher, err := des.NewCipher(generateDesKey(key)) + if err != nil { + panic("des: failed to create cipher: " + err.Error()) } - encrypted := make([]byte, len(plain)) - cipher, _ := des.NewCipher(generateDesKey(key)) + blockSize := cipher.BlockSize() + padded := pkcs5Padding(data, blockSize) + encrypted := make([]byte, len(padded)) - for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { - cipher.Encrypt(encrypted[bs:be], plain[bs:be]) + for i := 0; i < len(padded); i += blockSize { + cipher.Encrypt(encrypted[i:], padded[i:]) } return encrypted @@ -325,42 +409,50 @@ func DesEcbEncrypt(data, key []byte) []byte { // len(key) should be 8. // Play: https://go.dev/play/p/8qivmPeZy4P func DesEcbDecrypt(encrypted, key []byte) []byte { - cipher, _ := des.NewCipher(generateDesKey(key)) + cipher, err := des.NewCipher(generateDesKey(key)) + if err != nil { + panic("des: failed to create cipher: " + err.Error()) + } + + blockSize := cipher.BlockSize() + if len(encrypted)%blockSize != 0 { + panic("des: invalid encrypted data length") + } + decrypted := make([]byte, len(encrypted)) - - for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { - cipher.Decrypt(decrypted[bs:be], encrypted[bs:be]) + for i := 0; i < len(encrypted); i += blockSize { + cipher.Decrypt(decrypted[i:], encrypted[i:]) } - trim := 0 - if len(decrypted) > 0 { - trim = len(decrypted) - int(decrypted[len(decrypted)-1]) - } - - return decrypted[:trim] + // Remove padding + return pkcs5UnPadding(decrypted) } // DesCbcEncrypt encrypt data with key use DES CBC algorithm // len(key) should be 8. // Play: https://go.dev/play/p/4cC4QvWfe3_1 func DesCbcEncrypt(data, key []byte) []byte { - size := len(key) - if size != 8 { - panic("key length shoud be 8") + if len(key) != 8 { + panic("des: key length must be 8 bytes") } - block, _ := des.NewCipher(key) - data = pkcs7Padding(data, block.BlockSize()) + block, err := des.NewCipher(key) + if err != nil { + panic("des: failed to create cipher: " + err.Error()) + } - encrypted := make([]byte, des.BlockSize+len(data)) - iv := encrypted[:des.BlockSize] + blockSize := block.BlockSize() + data = pkcs7Padding(data, blockSize) + + encrypted := make([]byte, blockSize+len(data)) + iv := encrypted[:blockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) + panic("des: failed to generate IV: " + err.Error()) } mode := cipher.NewCBCEncrypter(block, iv) - mode.CryptBlocks(encrypted[des.BlockSize:], data) + mode.CryptBlocks(encrypted[blockSize:], data) return encrypted } @@ -369,26 +461,33 @@ func DesCbcEncrypt(data, key []byte) []byte { // len(key) should be 8. // Play: https://go.dev/play/p/4cC4QvWfe3_1 func DesCbcDecrypt(encrypted, key []byte) []byte { - size := len(key) - if size != 8 { - panic("key length shoud be 8") + if len(key) != 8 { + panic("des: key length must be 8 bytes") } - block, _ := des.NewCipher(key) + block, err := des.NewCipher(key) + if err != nil { + panic("des: failed to create cipher: " + err.Error()) + } - iv := encrypted[:des.BlockSize] - encrypted = encrypted[des.BlockSize:] + blockSize := block.BlockSize() + if len(encrypted) < blockSize || len(encrypted)%blockSize != 0 { + panic("des: invalid encrypted data length") + } + + iv := encrypted[:blockSize] + ciphertext := encrypted[blockSize:] mode := cipher.NewCBCDecrypter(block, iv) - mode.CryptBlocks(encrypted, encrypted) + mode.CryptBlocks(ciphertext, ciphertext) - decrypted := pkcs7UnPadding(encrypted) - return decrypted + return pkcs7UnPadding(ciphertext) } // DesCtrCrypt encrypt data with key use DES CTR algorithm // len(key) should be 8. // Play: https://go.dev/play/p/9-T6OjKpcdw +// deprecated: use DesCtrEncrypt and DesCtrDecrypt instead. func DesCtrCrypt(data, key []byte) []byte { size := len(key) if size != 8 { @@ -406,25 +505,83 @@ func DesCtrCrypt(data, key []byte) []byte { return dst } -// DesCfbEncrypt encrypt data with key use DES CFB algorithm +// DesCtrEncrypt encrypt data with key use DES CTR algorithm // len(key) should be 8. -// Play: https://go.dev/play/p/y-eNxcFBlxL -func DesCfbEncrypt(data, key []byte) []byte { - size := len(key) - if size != 8 { - panic("key length shoud be 8") +// Play: todo +func DesCtrEncrypt(data, key []byte) []byte { + if len(key) != 8 { + panic("des: key length must be 8 bytes") } block, err := des.NewCipher(key) if err != nil { - panic(err) + panic("des: failed to create cipher: " + err.Error()) + } + + iv := make([]byte, block.BlockSize()) + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + panic("des: failed to generate IV: " + err.Error()) + } + + stream := cipher.NewCTR(block, iv) + + encrypted := make([]byte, len(data)) + stream.XORKeyStream(encrypted, data) + + // 返回前缀包含 IV,便于解密 + return append(iv, encrypted...) +} + +// DesCtrDecrypt decrypt data with key use DES CTR algorithm +// len(key) should be 8. +// Play: todo +func DesCtrDecrypt(encrypted, key []byte) []byte { + if len(key) != 8 { + panic("des: key length must be 8 bytes") + } + + block, err := des.NewCipher(key) + if err != nil { + panic("des: failed to create cipher: " + err.Error()) + } + + blockSize := block.BlockSize() + if len(encrypted) < blockSize { + panic("des: ciphertext too short") + } + + iv := encrypted[:blockSize] + ciphertext := encrypted[blockSize:] + + stream := cipher.NewCTR(block, iv) + + decrypted := make([]byte, len(ciphertext)) + stream.XORKeyStream(decrypted, ciphertext) + + return decrypted +} + +// DesCfbEncrypt encrypt data with key use DES CFB algorithm +// len(key) should be 8. +// Play: https://go.dev/play/p/y-eNxcFBlxL +func DesCfbEncrypt(data, key []byte) []byte { + if len(key) != 8 { + panic("des: key length must be 8 bytes") + } + + block, err := des.NewCipher(key) + if err != nil { + panic("des: failed to create cipher: " + err.Error()) + } + + iv := make([]byte, des.BlockSize) + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + panic("des: failed to generate IV: " + err.Error()) } encrypted := make([]byte, des.BlockSize+len(data)) - iv := encrypted[:des.BlockSize] - if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) - } + + copy(encrypted[:des.BlockSize], iv) stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(encrypted[des.BlockSize:], data) @@ -436,44 +593,51 @@ func DesCfbEncrypt(data, key []byte) []byte { // len(encrypted) should be great than 16, len(key) should be 8. // Play: https://go.dev/play/p/y-eNxcFBlxL func DesCfbDecrypt(encrypted, key []byte) []byte { - size := len(key) - if size != 8 { - panic("key length shoud be 8") + if len(key) != 8 { + panic("des: key length must be 8 bytes") } - block, _ := des.NewCipher(key) - if len(encrypted) < des.BlockSize { - panic("encrypted data is too short") + block, err := des.NewCipher(key) + if err != nil { + panic("des: failed to create cipher: " + err.Error()) } + + if len(encrypted) < des.BlockSize { + panic("des: encrypted data too short") + } + iv := encrypted[:des.BlockSize] - encrypted = encrypted[des.BlockSize:] + ciphertext := encrypted[des.BlockSize:] stream := cipher.NewCFBDecrypter(block, iv) - stream.XORKeyStream(encrypted, encrypted) + stream.XORKeyStream(ciphertext, ciphertext) - return encrypted + return ciphertext } // DesOfbEncrypt encrypt data with key use DES OFB algorithm // len(key) should be 8. // Play: https://go.dev/play/p/74KmNadjN1J func DesOfbEncrypt(data, key []byte) []byte { - size := len(key) - if size != 8 { - panic("key length shoud be 8") + if len(key) != 8 { + panic("des: key length must be 8 bytes") } block, err := des.NewCipher(key) if err != nil { - panic(err) + panic("des: failed to create cipher: " + err.Error()) } + data = pkcs7Padding(data, des.BlockSize) - encrypted := make([]byte, des.BlockSize+len(data)) - iv := encrypted[:des.BlockSize] + + iv := make([]byte, des.BlockSize) if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic(err) + panic("des: failed to generate IV: " + err.Error()) } + encrypted := make([]byte, des.BlockSize+len(data)) + copy(encrypted[:des.BlockSize], iv) + stream := cipher.NewOFB(block, iv) stream.XORKeyStream(encrypted[des.BlockSize:], data) @@ -484,25 +648,25 @@ func DesOfbEncrypt(data, key []byte) []byte { // len(key) should be 8. // Play: https://go.dev/play/p/74KmNadjN1J func DesOfbDecrypt(data, key []byte) []byte { - size := len(key) - if size != 8 { - panic("key length shoud be 8") + if len(key) != 8 { + panic("des: key length must be 8 bytes") } block, err := des.NewCipher(key) if err != nil { - panic(err) + panic("des: failed to create cipher: " + err.Error()) + } + + if len(data) < des.BlockSize { + panic("des: encrypted data too short") } iv := data[:des.BlockSize] - data = data[des.BlockSize:] - if len(data)%des.BlockSize != 0 { - return nil - } + ciphertext := data[des.BlockSize:] - decrypted := make([]byte, len(data)) - mode := cipher.NewOFB(block, iv) - mode.XORKeyStream(decrypted, data) + stream := cipher.NewOFB(block, iv) + decrypted := make([]byte, len(ciphertext)) + stream.XORKeyStream(decrypted, ciphertext) decrypted = pkcs7UnPadding(decrypted) @@ -693,117 +857,3 @@ func RsaVerifySign(hash crypto.Hash, data, signature []byte, pubKeyFileName stri return rsa.VerifyPKCS1v15(publicKey, hash, hashed, signature) } - -// loadRsaPrivateKey loads and parses a PEM encoded private key file. -func loadRsaPublicKey(filename string) (*rsa.PublicKey, error) { - pubKeyData, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - - block, _ := pem.Decode(pubKeyData) - if block == nil { - return nil, errors.New("failed to decode PEM block containing the public key") - } - - var pubKey *rsa.PublicKey - blockType := strings.ToUpper(block.Type) - - if blockType == "RSA PUBLIC KEY" { - pubKey, err = x509.ParsePKCS1PublicKey(block.Bytes) - if err != nil { - key, err := x509.ParsePKIXPublicKey(block.Bytes) - if err != nil { - return nil, err - } - - var ok bool - pubKey, ok = key.(*rsa.PublicKey) - if !ok { - return nil, errors.New("failed to parse RSA private key") - } - } - } else if blockType == "PUBLIC KEY" { - key, err := x509.ParsePKIXPublicKey(block.Bytes) - if err != nil { - return nil, err - } - - var ok bool - pubKey, ok = key.(*rsa.PublicKey) - if !ok { - return nil, errors.New("failed to parse RSA private key") - } - - } else { - return nil, errors.New("unsupported key type") - } - - return pubKey, nil -} - -// loadRsaPrivateKey loads and parses a PEM encoded private key file. -func loadRasPrivateKey(filename string) (*rsa.PrivateKey, error) { - priKeyData, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - - block, _ := pem.Decode(priKeyData) - if block == nil { - return nil, errors.New("failed to decode PEM block containing the private key") - } - - var privateKey *rsa.PrivateKey - blockType := strings.ToUpper(block.Type) - - // PKCS#1 format - if blockType == "RSA PRIVATE KEY" { - privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) - if err != nil { - return nil, err - } - } else if blockType == "PRIVATE KEY" { // PKCS#8 format - priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) - if err != nil { - return nil, err - } - var ok bool - privateKey, ok = priKey.(*rsa.PrivateKey) - if !ok { - return nil, errors.New("failed to parse RSA private key") - } - } else { - return nil, errors.New("unsupported key type") - } - - return privateKey, nil -} - -// hashData returns the hash value of the data, using the specified hash function -func hashData(hash crypto.Hash, data []byte) ([]byte, error) { - if !hash.Available() { - return nil, errors.New("unsupported hash algorithm") - } - - var hashed []byte - - switch hash { - case crypto.SHA224: - h := sha256.Sum224(data) - hashed = h[:] - case crypto.SHA256: - h := sha256.Sum256(data) - hashed = h[:] - case crypto.SHA384: - h := sha512.Sum384(data) - hashed = h[:] - case crypto.SHA512: - h := sha512.Sum512(data) - hashed = h[:] - default: - return nil, errors.New("unsupported hash algorithm") - } - - return hashed, nil -} diff --git a/cryptor/crypto_internal.go b/cryptor/crypto_internal.go index cbdd186..e458386 100644 --- a/cryptor/crypto_internal.go +++ b/cryptor/crypto_internal.go @@ -1,6 +1,17 @@ package cryptor -import "bytes" +import ( + "bytes" + "crypto" + "crypto/rsa" + "crypto/sha256" + "crypto/sha512" + "crypto/x509" + "encoding/pem" + "errors" + "os" + "strings" +) func generateAesKey(key []byte, size int) []byte { genKey := make([]byte, size) @@ -35,3 +46,139 @@ func pkcs7UnPadding(src []byte) []byte { unPadding := int(src[length-1]) return src[:(length - unPadding)] } + +func pkcs5Padding(data []byte, blockSize int) []byte { + padding := blockSize - len(data)%blockSize + padText := bytes.Repeat([]byte{byte(padding)}, padding) + return append(data, padText...) +} + +func pkcs5UnPadding(data []byte) []byte { + length := len(data) + if length == 0 { + return nil + } + padLen := int(data[length-1]) + if padLen == 0 || padLen > length { + return nil + } + return data[:length-padLen] +} + +func isAesKeyLengthValid(n int) bool { + return n == 16 || n == 24 || n == 32 +} + +// loadRsaPrivateKey loads and parses a PEM encoded private key file. +func loadRsaPublicKey(filename string) (*rsa.PublicKey, error) { + pubKeyData, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + + block, _ := pem.Decode(pubKeyData) + if block == nil { + return nil, errors.New("failed to decode PEM block containing the public key") + } + + var pubKey *rsa.PublicKey + blockType := strings.ToUpper(block.Type) + + if blockType == "RSA PUBLIC KEY" { + pubKey, err = x509.ParsePKCS1PublicKey(block.Bytes) + if err != nil { + key, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, err + } + + var ok bool + pubKey, ok = key.(*rsa.PublicKey) + if !ok { + return nil, errors.New("failed to parse RSA private key") + } + } + } else if blockType == "PUBLIC KEY" { + key, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, err + } + + var ok bool + pubKey, ok = key.(*rsa.PublicKey) + if !ok { + return nil, errors.New("failed to parse RSA private key") + } + + } else { + return nil, errors.New("unsupported key type") + } + + return pubKey, nil +} + +// loadRsaPrivateKey loads and parses a PEM encoded private key file. +func loadRasPrivateKey(filename string) (*rsa.PrivateKey, error) { + priKeyData, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + + block, _ := pem.Decode(priKeyData) + if block == nil { + return nil, errors.New("failed to decode PEM block containing the private key") + } + + var privateKey *rsa.PrivateKey + blockType := strings.ToUpper(block.Type) + + // PKCS#1 format + if blockType == "RSA PRIVATE KEY" { + privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + } else if blockType == "PRIVATE KEY" { // PKCS#8 format + priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + var ok bool + privateKey, ok = priKey.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("failed to parse RSA private key") + } + } else { + return nil, errors.New("unsupported key type") + } + + return privateKey, nil +} + +// hashData returns the hash value of the data, using the specified hash function +func hashData(hash crypto.Hash, data []byte) ([]byte, error) { + if !hash.Available() { + return nil, errors.New("unsupported hash algorithm") + } + + var hashed []byte + + switch hash { + case crypto.SHA224: + h := sha256.Sum224(data) + hashed = h[:] + case crypto.SHA256: + h := sha256.Sum256(data) + hashed = h[:] + case crypto.SHA384: + h := sha512.Sum384(data) + hashed = h[:] + case crypto.SHA512: + h := sha512.Sum512(data) + hashed = h[:] + default: + return nil, errors.New("unsupported hash algorithm") + } + + return hashed, nil +} diff --git a/cryptor/crypto_test.go b/cryptor/crypto_test.go index 70b7b2c..c44fa8b 100644 --- a/cryptor/crypto_test.go +++ b/cryptor/crypto_test.go @@ -7,7 +7,7 @@ import ( "github.com/duke-git/lancet/v2/internal" ) -func TestAesEcbEncrypt(t *testing.T) { +func TestAesEcbCrypt(t *testing.T) { t.Parallel() data := "hello world" @@ -16,11 +16,11 @@ func TestAesEcbEncrypt(t *testing.T) { aesEcbEncrypt := AesEcbEncrypt([]byte(data), []byte(key)) aesEcbDecrypt := AesEcbDecrypt(aesEcbEncrypt, []byte(key)) - assert := internal.NewAssert(t, "TestAesEcbEncrypt") + assert := internal.NewAssert(t, "TestAesEcbCrypt") assert.Equal(data, string(aesEcbDecrypt)) } -func TestAesCbcEncrypt(t *testing.T) { +func TestAesCbcCrypt(t *testing.T) { t.Parallel() data := "hello world" @@ -29,7 +29,7 @@ func TestAesCbcEncrypt(t *testing.T) { aesCbcEncrypt := AesCbcEncrypt([]byte(data), []byte(key)) aesCbcDecrypt := AesCbcDecrypt(aesCbcEncrypt, []byte(key)) - assert := internal.NewAssert(t, "TestAesCbcEncrypt") + assert := internal.NewAssert(t, "TestAesCbcCrypt") assert.Equal(data, string(aesCbcDecrypt)) } @@ -39,14 +39,14 @@ func TestAesCtrCrypt(t *testing.T) { data := "hello world" key := "abcdefghijklmnop" - aesCtrCrypt := AesCtrCrypt([]byte(data), []byte(key)) - aesCtrDeCrypt := AesCtrCrypt(aesCtrCrypt, []byte(key)) + aesCtrCrypt := AesCtrEncrypt([]byte(data), []byte(key)) + aesCtrDeCrypt := AesCtrDecrypt(aesCtrCrypt, []byte(key)) assert := internal.NewAssert(t, "TestAesCtrCrypt") assert.Equal(data, string(aesCtrDeCrypt)) } -func TestAesCfbEncrypt(t *testing.T) { +func TestAesCfbCrypt(t *testing.T) { t.Parallel() data := "hello world" @@ -55,11 +55,11 @@ func TestAesCfbEncrypt(t *testing.T) { aesCfbEncrypt := AesCfbEncrypt([]byte(data), []byte(key)) aesCfbDecrypt := AesCfbDecrypt(aesCfbEncrypt, []byte(key)) - assert := internal.NewAssert(t, "TestAesCfbEncrypt") + assert := internal.NewAssert(t, "TestAesCfbCrypt") assert.Equal(data, string(aesCfbDecrypt)) } -func TestAesOfbEncrypt(t *testing.T) { +func TestAesOfbCrypt(t *testing.T) { t.Parallel() data := "hello world" @@ -72,7 +72,7 @@ func TestAesOfbEncrypt(t *testing.T) { assert.Equal(data, string(aesOfbDecrypt)) } -func TestDesEcbEncrypt(t *testing.T) { +func TestDesEcbCrypt(t *testing.T) { t.Parallel() data := "hello world" @@ -85,7 +85,7 @@ func TestDesEcbEncrypt(t *testing.T) { assert.Equal(data, string(desEcbDecrypt)) } -func TestDesCbcEncrypt(t *testing.T) { +func TestDesCbcCrypt(t *testing.T) { t.Parallel() data := "hello world" @@ -104,14 +104,14 @@ func TestDesCtrCrypt(t *testing.T) { data := "hello world" key := "abcdefgh" - desCtrCrypt := DesCtrCrypt([]byte(data), []byte(key)) - desCtrDeCrypt := DesCtrCrypt(desCtrCrypt, []byte(key)) + desCtrCrypt := DesCtrEncrypt([]byte(data), []byte(key)) + desCtrDeCrypt := DesCtrDecrypt(desCtrCrypt, []byte(key)) assert := internal.NewAssert(t, "TestDesCtrCrypt") assert.Equal(data, string(desCtrDeCrypt)) } -func TestDesCfbEncrypt(t *testing.T) { +func TestDesCfbCrypt(t *testing.T) { t.Parallel() data := "hello world" @@ -124,7 +124,7 @@ func TestDesCfbEncrypt(t *testing.T) { assert.Equal(data, string(desCfbDecrypt)) } -func TestDesOfbEncrypt(t *testing.T) { +func TestDesOfbCrypt(t *testing.T) { t.Parallel() data := "hello world" diff --git a/cryptor/rsa_private_example.pem b/cryptor/rsa_private_example.pem index 98cc2ff..b06f5b0 100644 --- a/cryptor/rsa_private_example.pem +++ b/cryptor/rsa_private_example.pem @@ -1,51 +1,51 @@ -----BEGIN rsa private key----- -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 -----END rsa private key----- diff --git a/cryptor/rsa_public_example.pem b/cryptor/rsa_public_example.pem index 1734761..85de307 100644 --- a/cryptor/rsa_public_example.pem +++ b/cryptor/rsa_public_example.pem @@ -1,14 +1,14 @@ -----BEGIN rsa public key----- -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtXr+2FbR6Prdf9U0gfq2 -OJbTD82m84bbdeyfsakabYp8Haw6mZW6ebRNPJvQ87H6DbA55hK1E7y6m+wjvbUo -pnkGh75Cp04CoQvaU8Rs7MrQcJ2Zz1VRRgugmqwJMWE/FC5eGXvvpDjF2h2lqThK -ZTKcvhqfZ3dNX+6v4EQ4BbjSGKdzpyexzR1WSV9IzZYRHMk8jCoEHOx9ItEzoToB -f9yAq0DhufylqSRbjKLhR7A3IiRSLVNfu0Sz5cfNlS7eUA060QS8AV9BgGNTkl75 -aj8BCOmoHIW85SsSZvdQWYwmlM76Jn+tfNNnY7Uuqtz2gI1odcy1nXembXWJryxu -YCkSAwpU8UNIQpZeKwBnBxaf0pj3W1m3UzEqhGkkCrKq8LkNSGZSkhT+bI65fNx2 -LZ7lS165szkeyqS8aikxcBpdx7Z/bqbFFuI42KX+IpXAJCAtvsQ0XXinr83MLcY/ -I2Ic/5Sgz7txfZsKKwKt48ETS9BjxGPWo1Dd5YjM8ZJWJv2Rf0mwVjUMClFSNBm8 -x+aWGVIKjpocN/plpEZmFrWdPcWM4ZH3qGCEnVVkqPvqClahNSQXsM4W7msYts1I -Uq31tjBSV5bL6l2K8jFJa4PRYdzh1vHhDOAYTpgDkQbNaoDlDS2o/0TkAGUfXWJt -R3D35wRJzoa7bCMt5BuFE3sCAwEAAQ== +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvEyrhW9xP2vi2ONaQqIL +GOpqk3UJZRnT9ItEpefUvsjYeL3QdR9VMngVV8MtmhwqAut7h+aDGL4ZWIj4vh9e +zIHNPkIUZwm3qA/Q0IZ1+/8tZN3U7pBfIYvM0kW6Ko9U9LRMha/2WhG0NWHeZKYn +t2dPg/FhoRSvh2fswW+TXK4KbEK0FcBC9hjAlQsz/CHqeZSF+EEZdvFwenvvr8vv +QRNGaTAgqkqQKcek5CaJAKw0N926mwb9k3aHXN0XuK94vkmS1RKrsQSiSOpkioLI +2DUPryayddokjmszkdHggv2uVR6sa/RTwtU0nZjD02+F+3vYYoo+dx4hpCV8Ln8I +thtABCohEGW+M3IU+0vMRFgtRtLSGqGZ3vYGCt12tUsPNHFrPE1i8YPJDF4e8V7A +qdKrPgoKHyn8mb7Ho0uZ0GItzrPUuPROBmoAcwwYR9AOTLDR+ZFmZ+bfUXO03nLW +XF+MbnLDvKLE5bNdyjgEf4hzuHCwX5UfQgpHt3c+nbm54ds82bWHrWFwW3/x8FGQ +ZtlPYYMYYX/js+g/frYHGmjhYbbyvfoK15GKDM+YwzBkZqA2yU50ytjfkFjcRp/P +p8v2AolbnjVqYS2oUgNJUG80wunUQjO1FaJNAk239Y3cZ71A698eKWMDkdkiMnv2 +CXyMfSc/bBL/dtP2/nMzmhcCAwEAAQ== -----END rsa public key-----