md5 加密——不可逆
MD5信息摘要算法是一种被广泛使用的密码散列函数,可以产生出一个128位(16进制,32个字符)的散列值(hash value),用于确保信息传输完整一致。
1 2 3 4 5
| import ( "crypto/md5" "encoding/hex" "fmt" )
|
第一种
1 2 3 4 5 6 7
| func MD5Str(src string) string { h := md5.New() h.Write([]byte(src)) fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) return hex.EncodeToString(h.Sum(nil)) }
|
第二种
1 2 3 4
| func MD5Str2(src string) string { return fmt.Sprintf("%x", md5.Sum([]byte(src))) }
|
hmacsha 加密——不可逆
HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,
它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中。
和我们自定义的加salt算法不同,Hmac算法针对所有哈希算法都通用,无论是MD5还是SHA-1。采用Hmac替代我们自己的salt算法,可以使程序算法更标准化,也更安全。
hmac-md5加密
1 2 3 4 5 6 7 8 9 10 11 12
|
func Hmac(key, data string) string { hash:= hmac.New(md5.New, []byte(key))
hash.Write([]byte(data))
return hex.EncodeToString(hash.Sum([]byte("")))
}
|
hamacsha1 加密
1 2 3 4 5 6
| func HmacSha1(src, key string) string { m := hmac.New(sha1.New, []byte(key)) m.Write([]byte(src)) return hex.EncodeToString(m.Sum(nil)) }
|
hamacsha 256 加密
1 2 3 4 5 6
| func HmacSHA256(key, src string) string { m := hmac.New(sha256.New, []byte(key)) m.Write([]byte(src)) return hex.EncodeToString(m.Sum(nil)) }
|
hmacsha512加密
1 2 3 4 5 6
| func HmacSHA512(key, src string) string { m := hmac.New(sha512.New, []byte(key)) m.Write([]byte(src)) return hex.EncodeToString(m.Sum(nil)) }
|
hamasha 调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| package main
import ( "crypto/hmac" "crypto/md5" "crypto/sha1" "crypto/sha256" "crypto/sha512" "encoding/hex" "fmt" )
func Hmac(key, data string) string {
hash := hmac.New(md5.New, []byte(key))
hash.Write([]byte(data))
return hex.EncodeToString(hash.Sum([]byte("")))
}
func HmacSHA256(key, src string) string { m := hmac.New(sha256.New, []byte(key)) m.Write([]byte(src)) return hex.EncodeToString(m.Sum(nil)) }
func HmacSHA512(key, src string) string { m := hmac.New(sha512.New, []byte(key)) m.Write([]byte(src)) return hex.EncodeToString(m.Sum(nil)) }
func HmacSha1(src, key string) string { m := hmac.New(sha1.New, []byte(key)) m.Write([]byte(src)) return hex.EncodeToString(m.Sum(nil)) }
func SHA256Str(src string) string { h := sha256.New() h.Write([]byte(src)) return hex.EncodeToString(h.Sum(nil)) }
func main() { hmac_ := Hmac("hybpjx", "始識") hamcsha1 := HmacSha1("hybpjx", "始識") hamcsha256 := HmacSHA256("hybpjx", "始識") hamacsha512 := HmacSHA512("hybpjx", "始識") fmt.Println(hmac_) fmt.Println(hamcsha1) fmt.Println(hamcsha256) fmt.Println(hamacsha512) }
|
结果
d8801f70df7891764116e1ac003f7189
60d68e01c8a86f3b87e4e147e9f0fadce2a69661
b3f8ddf991288036864761a55046877adfe4f78ec9a89bb63932af92689b139f
b9b1fca0fe91522482ee1b2161e57d67482af6ef371614365b918c31ce774f9126ed627e378a063145f404ff2de7bd84f8e4798c385662ef4749e58e9209ca63
Sha 加密——不可逆
sha1
SHA-1可以生成一个被称为消息摘要的160位(20字节)散列值,散列值通常的呈现形式为40个十六进制数。
1 2 3 4 5
| func Sha1(data string) string { sha1_ := sha1.New() sha1_.Write([]byte(data)) return hex.EncodeToString(sha1_.Sum([]byte(""))) }
|
sha256
SHA256算法使用的哈希值长度是256位。这是一个抽象类。此类的唯一实现是SHA256Managed。
1 2 3 4 5 6 7 8
| func SHA256(src string) string { h := sha256.New() h.Write([]byte(src)) return hex.EncodeToString(h.Sum(nil)) }
|
sha512
SHA (Secure Hash Algorithm,译作安全散列算法) 是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院 (NIST) 发布的一系列密码散列函数。
1 2 3 4 5 6 7 8
| func SHA512(src string) string { h := sha512.New() h.Write([]byte(src)) return hex.EncodeToString(h.Sum(nil)) }
|
sha调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package main
import ( "crypto/sha1" "crypto/sha256" "crypto/sha512" "encoding/hex" "fmt" )
func Sha1(data string) string { sha1_ := sha1.New() sha1_.Write([]byte(data)) return hex.EncodeToString(sha1_.Sum([]byte(""))) }
func SHA256(src string) string { h := sha256.New() h.Write([]byte(src)) return hex.EncodeToString(h.Sum(nil)) }
func SHA512(src string) string { h := sha512.New() h.Write([]byte(src)) return hex.EncodeToString(h.Sum(nil)) }
func main() { _sha1 := Sha1("始識") _sha256 := SHA256("始識") _sha512 := SHA512("始識") fmt.Println(_sha1) fmt.Println(_sha256) fmt.Println(_sha512) }
|
结果
7bac01cc58a26f3cb280b0466794a89441279946
6ef99e6d3fe34a46afcdc438435728fe95ffdab18e389ddd31609edd6729b11d
0c04e9b79f488646d0eac6f65468248507939d643cc92709b14eb0d18d8f13db509ed5ccd3312d6c234408185a4611a42525dce9e8d32255640f56a2f836635a
base 加密 解密
加密
1 2 3 4 5
| func BASE64StdEncode(src string) string { return base64.StdEncoding.EncodeToString([]byte(src)) }
|
解密
1 2 3 4 5 6 7 8
| func BASE64StdDecode(src string) string { a, err := base64.StdEncoding.DecodeString(src) if err != nil { _ = fmt.Errorf("解密失败,%v\n", err) } return string(a) }
|
base64 调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package main
import ( "encoding/base64" "fmt" )
func BASE64StdEncode(src string) string { return base64.StdEncoding.EncodeToString([]byte(src)) }
func BASE64StdDecode(src string) string { a, err := base64.StdEncoding.DecodeString(src) if err != nil { _ = fmt.Errorf("解密失败,%v\n", err) } return string(a) }
func main() { encodeBase64 := BASE64StdEncode("hybpjx") decodeBase64 := BASE64StdDecode(encodeBase64) fmt.Println(encodeBase64) fmt.Println(decodeBase64) }
|
结果
aHlicGp4
hybpjx
AES 加密
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

由于加密和解密的秘钥是相同的,所以AES为对称加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| package main
import ( "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" "fmt" )
func PKCS7Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) }
func PKCS7UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] }
func AesEncrypt(origData, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() origData = PKCS7Padding(origData, blockSize) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) crypted := make([]byte, len(origData)) blockMode.CryptBlocks(crypted, origData) return crypted, nil }
func AesDecrypt(crypted, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) origData := make([]byte, len(crypted)) blockMode.CryptBlocks(origData, crypted) origData = PKCS7UnPadding(origData) return origData, nil }
func main() { text := "今晚打老虎" AesKey := []byte("0f90023fc9ae101e") fmt.Printf("明文: %s\n秘钥: %s\n", text, string(AesKey)) encrypted, err := AesEncrypt([]byte(text), AesKey) if err != nil { panic(err) } fmt.Printf("加密后: %s\n", base64.StdEncoding.EncodeToString(encrypted)) origin, err := AesDecrypt(encrypted, AesKey) if err != nil { panic(err) } fmt.Printf("解密后明文: %s\n", string(origin)) }
|
CBC方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| package main
import ( "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" "encoding/hex" "log" )
func AesEncryptCBC(origData []byte, key []byte) (encrypted []byte) { block, _ := aes.NewCipher(key) blockSize := block.BlockSize() origData = pkcs5Padding(origData, blockSize) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) encrypted = make([]byte, len(origData)) blockMode.CryptBlocks(encrypted, origData) return encrypted } func AesDecryptCBC(encrypted []byte, key []byte) (decrypted []byte) { block, _ := aes.NewCipher(key) blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) decrypted = make([]byte, len(encrypted)) blockMode.CryptBlocks(decrypted, encrypted) decrypted = pkcs5UnPadding(decrypted) return decrypted } func pkcs5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func pkcs5UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] } func main() { origData := []byte("460154561234") key := []byte("9876787656785679") log.Println("原文:", string(origData))
log.Println("------------------ CBC模式 --------------------") encrypted := AesEncryptCBC(origData, key) log.Println("密文(hex):", hex.EncodeToString(encrypted)) log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted)) decrypted := AesDecryptCBC(encrypted, key) log.Println("解密结果:", string(decrypted)) }
|
ECB方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| package main
import ( "crypto/aes" "encoding/base64" "encoding/hex" "log" )
func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) { cipher, _ := aes.NewCipher(generateKey(key)) length := (len(origData) + aes.BlockSize) / aes.BlockSize plain := make([]byte, length*aes.BlockSize) copy(plain, origData) pad := byte(len(plain) - len(origData)) for i := len(origData); i < len(plain); i++ { plain[i] = pad } encrypted = make([]byte, len(plain)) for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { cipher.Encrypt(encrypted[bs:be], plain[bs:be]) }
return encrypted } func AesDecryptECB(encrypted []byte, key []byte) (decrypted []byte) { cipher, _ := aes.NewCipher(generateKey(key)) 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]) }
trim := 0 if len(decrypted) > 0 { trim = len(decrypted) - int(decrypted[len(decrypted)-1]) }
return decrypted[:trim] } func generateKey(key []byte) (genKey []byte) { genKey = make([]byte, 16) copy(genKey, key) for i := 16; i < len(key); { for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 { genKey[j] ^= key[i] } } return genKey }
func main() { origData := []byte("460154561234") key := []byte("9876787656785679") log.Println("原文:", string(origData))
log.Println("------------------ ECB模式 --------------------") encrypted := AesEncryptECB(origData, key) log.Println("密文(hex):", hex.EncodeToString(encrypted)) log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted)) decrypted := AesDecryptECB(encrypted, key) log.Println("解密结果:", string(decrypted)) }
|
CFB 方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package main
import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "encoding/hex" "io" "log" )
func AesEncryptCFB(origData []byte, key []byte) (encrypted []byte) { block, err := aes.NewCipher(key) if err != nil { panic(err) } encrypted = make([]byte, aes.BlockSize+len(origData)) iv := encrypted[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic(err) } stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(encrypted[aes.BlockSize:], origData) return encrypted } func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) { block, _ := aes.NewCipher(key) if len(encrypted) < aes.BlockSize { panic("ciphertext too short") } iv := encrypted[:aes.BlockSize] encrypted = encrypted[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv) stream.XORKeyStream(encrypted, encrypted) return encrypted } func main() { origData := []byte("460154561234") key := []byte("9876787656785679") log.Println("原文:", string(origData))
log.Println("------------------ CFB模式 --------------------") encrypted := AesEncryptCFB(origData, key) log.Println("密文(hex):", hex.EncodeToString(encrypted)) log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted)) decrypted := AesDecryptCFB(encrypted, key) log.Println("解密结果:", string(decrypted)) }
|
RSA加密
RSA是一种基于公钥密码体制的优秀加密算法,1978年由美国(MIT)的李维斯特(Rivest)、沙米尔(Shamir)、艾德曼(Adleman)提的。
RSA算法是一种分组密码体制算法,它的保密强度是建立在具有大素数因子的合数其因子分解是困难的(基于大数分解的难度)。
公钥和私钥是一对大素数的函数,从一个公钥和密文中恢复出明文的难度等价于分解两个大素数之积。
RSA得到了世界上的最广泛的应用,ISO在1992年颁布的国际标准X.509中,将RSA算法正式纳入国际标准。
RSA加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
| package main
import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" "os" )
func GenerateRSAKey(bits int){ privateKey, err := rsa.GenerateKey(rand.Reader, bits) if err!=nil{ panic(err) } X509PrivateKey,err := x509.MarshalPKCS8PrivateKey(privateKey) if err != nil { fmt.Println(err.Error()) os.Exit(0) } privateFile, err := os.Create("private.pem") if err!=nil{ panic(err) } defer privateFile.Close() privateBlock:= pem.Block{Type: "PRIVATE KEY",Bytes:X509PrivateKey} pem.Encode(privateFile,&privateBlock) publicKey:=privateKey.PublicKey X509PublicKey,err:=x509.MarshalPKIXPublicKey(&publicKey) if err!=nil{ panic(err) } publicFile, err := os.Create("public.pem") if err!=nil{ panic(err) } defer publicFile.Close() publicBlock:= pem.Block{Type: "Public Key",Bytes:X509PublicKey} pem.Encode(publicFile,&publicBlock) }
func RsaEncrypt(plainText []byte,path string)[]byte{ file,err:=os.Open(path) if err!=nil{ panic(err) } defer file.Close() info, _ := file.Stat() buf:=make([]byte,info.Size()) file.Read(buf) block, _ := pem.Decode(buf) publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err!=nil{ panic(err) } publicKey:=publicKeyInterface.(*rsa.PublicKey) cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText) if err!=nil{ panic(err) } return cipherText }
func RsaDecrypt(cipherText []byte,path string) []byte{ file,err:=os.Open(path) if err!=nil{ panic(err) } defer file.Close() info, _ := file.Stat() buf:=make([]byte,info.Size()) file.Read(buf) block, _ := pem.Decode(buf) privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err!=nil{ fmt.Println(err.Error()) os.Exit(0) } plainText,_:=rsa.DecryptPKCS1v15(rand.Reader,privateKey.(*rsa.PrivateKey),cipherText) return plainText }
func main(){
GenerateRSAKey(1024) publicPath := "public_key.pem" privatePath := "private_key.pem"
publicPath = "public.pem" privatePath = "private.pem"
txt := []byte("hello") encrptTxt := RsaEncrypt(txt,publicPath) decrptCode := RsaDecrypt(encrptTxt,privatePath) fmt.Println(string(decrptCode))
}
|
RSA分段加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
| package main
import ( "bytes" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" "log" "os" )
func main() { GenerateRSAKey(2048) publicPath := "public.pem" privatePath := "private.pem" var a = []byte("hello") encrptTxt, err := RsaEncryptBlock(a, publicPath) if err != nil { fmt.Println(err.Error()) } encodeString := base64.StdEncoding.EncodeToString(encrptTxt) decodeByte, err := base64.StdEncoding.DecodeString(encodeString) if err != nil { panic(err) } decrptCode := RSA_Decrypts(decodeByte, privatePath) fmt.Println(string(decrptCode))
}
func GenerateRSAKey(bits int) { privateKey, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { panic(err) } X509PrivateKey, err := x509.MarshalPKCS8PrivateKey(privateKey) if err != nil { fmt.Println(err.Error()) os.Exit(0) } privateFile, err := os.Create("private.pem") if err != nil { panic(err) } defer privateFile.Close() privateBlock := pem.Block{Type: "PRIVATE KEY", Bytes: X509PrivateKey} pem.Encode(privateFile, &privateBlock) publicKey := privateKey.PublicKey X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey) if err != nil { panic(err) } publicFile, err := os.Create("public.pem") if err != nil { panic(err) } defer publicFile.Close() publicBlock := pem.Block{Type: "Public Key", Bytes: X509PublicKey} pem.Encode(publicFile, &publicBlock) }
func RSA_Decrypts(cipherText []byte, path string) []byte { var bytesDecrypt []byte file, err := os.Open(path) if err != nil { panic(err) } defer file.Close() info, _ := file.Stat() buf := make([]byte, info.Size()) file.Read(buf) block, _ := pem.Decode(buf) privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { fmt.Println(err.Error()) os.Exit(0) } p := privateKey.(*rsa.PrivateKey) keySize := p.Size() srcSize := len(cipherText) log.Println("密钥长度", keySize, "密文长度", srcSize) var offSet = 0 var buffer = bytes.Buffer{} for offSet < srcSize { endIndex := offSet + keySize if endIndex > srcSize { endIndex = srcSize } bytesOnce, err := rsa.DecryptPKCS1v15(rand.Reader, p, cipherText[offSet:endIndex]) if err != nil { return nil } buffer.Write(bytesOnce) offSet = endIndex } bytesDecrypt = buffer.Bytes() return bytesDecrypt }
func RsaEncryptBlock(src []byte, path string) (bytesEncrypt []byte, err error) { file, err := os.Open(path) if err != nil { panic(err) } defer file.Close() info, _ := file.Stat() buf := make([]byte, info.Size()) file.Read(buf) block, _ := pem.Decode(buf) publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { panic(err) } publicKey := publicKeyInterface.(*rsa.PublicKey) keySize, srcSize := publicKey.Size(), len(src) log.Println("密钥长度", keySize, "明文长度", srcSize) offSet, once := 0, keySize-11 buffer := bytes.Buffer{} for offSet < srcSize { endIndex := offSet + once if endIndex > srcSize { endIndex = srcSize } bytesOnce, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, src[offSet:endIndex]) if err != nil { return nil, err } buffer.Write(bytesOnce) offSet = endIndex } bytesEncrypt = buffer.Bytes() return }
|
DES加密
- DES(Data Encryption)是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码(FIPS46-3),一直以来被美国及其他国家的政府和银行等广泛使用。随着计算机的进步,DES已经能够被暴力破解,1997年的DES Challenge I 中用了96天破译密钥,1998年的DES Challenge II-1中用了41天,1998年的DES Challenge II-2中用了56小时,1999年的DES Challenge III 中只用了22小时15分钟。
- DES是一种将64比特的明文加密成64比特的密文的对称密码算法,它的密钥的长度是56比特。尽管从规格上来说,DES的密钥长度是64比特,但由于每隔7比特会设置一个用于错误检查的比特,因此实质上其密钥长度是56比特。
- DES 是以64比特的明文(比特序列)为一个单位来进行加密的,这个64比特的单位称为分组 ,一般来说,以分组为单位进行处理的密码算法称为分组密码,DES就是分组密码的一种。
- DES每次只能加密64比特的数据,如果要加密的明文比较长,就需要对DES加密进行迭代(反复),而迭代的具体方式就称为模式。
- DES 内部实现理论:在 des 中各个步骤称为轮,整个加密过程进行16轮循环。
内置库完成
加密模式采用ECB、填充方式采用pkcs5padding、密码使用”12345678”,输出时经hex编码。自己可以通过一些在线测试工具进行测试,看结果是否一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package main
import ( "bytes" "crypto/cipher" "crypto/des" "encoding/hex" "fmt" )
func main() { data := []byte("hello world") key := []byte("12345678") iv := []byte("43218765")
result, err := DesCBCEncrypt(data, key, iv) if err != nil { fmt.Println(err) } b := hex.EncodeToString(result) fmt.Println(b) }
func DesCBCEncrypt(data, key, iv []byte) ([]byte, error) { block, err := des.NewCipher(key) if err != nil { return nil, err }
data = pkcs5Padding(data, block.BlockSize()) cryptText := make([]byte, len(data))
blockMode := cipher.NewCBCEncrypter(block, iv) blockMode.CryptBlocks(cryptText, data) return cryptText, nil }
func pkcs5Padding(cipherText []byte, blockSize int) []byte { padding := blockSize - len(cipherText)%blockSize padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(cipherText, padText...) }
|
使用第三方库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import ( "fmt" "github.com/marspere/goencrypt" )
func main() { cipher := goencrypt.NewDESCipher([]byte("12345678"), []byte(""), goencrypt.ECBMode, goencrypt.Pkcs7, goencrypt.PrintBase64) cipherText, err := cipher.DESEncrypt([]byte("hello world")) if err != nil { fmt.Println(err) return } fmt.Println(cipherText) }
|
3DES加密算法
3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。
由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
还有一个库 非常NB
ECB模式下的3DES算法加解密信息,golang默认只提供CBC模式
这边有golang的加密库,非常厉害
github.com/forgoer/openssl
安装:
go get github.com/thinkoner/openssl
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package main
import ( "encoding/base64" "encoding/hex" "fmt" "github.com/forgoer/openssl" )
func main() {
key := []byte("123456789012345678901234") fmt.Println("密钥:", key, hex.EncodeToString(key))
src := []byte("0102030109000000030000000F8898E37A7F8F3D742006111118080000FACE05")
encodeData, _ := openssl.Des3ECBEncrypt(src, key, openssl.ZEROS_PADDING) encryptBaseData := base64.StdEncoding.EncodeToString(encodeData)
fmt.Println("加密后Base64:", encryptBaseData) fmt.Println("加密后Hex:", hex.EncodeToString(encodeData))
decodeBaseData, _ := base64.StdEncoding.DecodeString(encryptBaseData) decodeData, _ := openssl.Des3ECBDecrypt(decodeBaseData, key, openssl.ZEROS_PADDING)
fmt.Println("解密后:", hex.EncodeToString(decodeData)) }
|
包括 Des的加密解密
以下只举一个例子
1 2 3 4 5 6
| srcData := "L0j+JvbeVM0svSpjIwXdE7yTu78wiEszCmW8rwjXY3vrx2nEaUeJ/Rw/c/IRdlxIH+/ro4pykx6ESOkGU1YwM8ddEuuoTg5uPsqQ9/SuNds=" key := []byte("Ctpsp@884*"[:8])
decodeBaseData, _ := base64.StdEncoding.DecodeString(srcData) decodeData, _ := openssl.DesECBDecrypt(decodeBaseData, key, openssl.PKCS5_PADDING) fmt.Println("解密后:", string(decodeData))
|