mirror of
https://github.com/duke-git/lancet.git
synced 2025-09-26 19:41:20 +08:00
fix: fix issue #159 and refact crypto function
This commit is contained in:
@@ -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 (
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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"
|
||||
|
@@ -1,51 +1,51 @@
|
||||
-----BEGIN rsa private key-----
|
||||
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
|
||||
-----END rsa private key-----
|
||||
|
@@ -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-----
|
||||
|
Reference in New Issue
Block a user