crypto
Crypto
https://golang.org/pkg/crypto/
SHA256
包含了sha224 與 sha256
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
sum := sha256.Sum256([]byte("hello world\n"))
fmt.Printf("%x", sum)
}
https://play.golang.org/p/Ky4kmHLqly
SHA3
(包含原生sha3和SHAKE)
The SHAKE instances are faster than the SHA3 instances
https://godoc.org/golang.org/x/crypto/sha3
package main
import (
"fmt"
"golang.org/x/crypto/sha3"
)
func main() {
buf := []byte("some")
h := make([]byte, 32)
d := sha3.NewShake256()
d.Write(buf)
d.Read(h)
fmt.Printf("%x\n", h)
}
等同於
package main
import (
"fmt"
"golang.org/x/crypto/sha3"
)
func main() {
buf := []byte("some")
// A hash needs to be 64 bytes long to have 256-bit collision resistance.
h := make([]byte, 32)
// Compute a 64-byte hash of buf and put it in h.
sha3.ShakeSum256(h, buf)
fmt.Printf("%x\n", h)
}
RIPEMD160
package main
import (
"golang.org/x/crypto/ripemd160"
"fmt"
)
func main() {
h := ripemd160.New()
h.Write([]byte("hello"))
fmt.Printf("%x\n", h.Sum(nil))
}
HMAC
https://golang.org/pkg/crypto/hmac/
package main
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
)
func main() {
key := []byte("I am key")
mac := hmac.New(sha256.New, key)
mac.Write([]byte("msg"))
fmt.Printf("%x\n", mac.Sum(nil))
}
ECDSA
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/md5"
"crypto/rand"
"fmt"
"hash"
"io"
"math/big"
"os"
)
func main() {
Curve := elliptic.P256() //see http://golang.org/pkg/crypto/elliptic/#P256
privatekey, err := ecdsa.GenerateKey(Curve, rand.Reader) // this generates a public & private key pair
if err != nil {
fmt.Println(err)
os.Exit(1)
}
pubkey := privatekey.PublicKey
fmt.Printf("%+v\n", privatekey.PublicKey.X)
fmt.Println("Private Key :")
fmt.Printf("%x \n", privatekey)
fmt.Println("Public Key :")
fmt.Printf("%x \n", pubkey)
fmt.Printf("%+v\n", pubkey) // 印出struct
// Sign ecdsa style
var h hash.Hash
h = md5.New()
r := big.NewInt(0)
s := big.NewInt(0)
io.WriteString(h, "This is a message to be signed and verified by ECDSA!")
signhash := h.Sum(nil)
r, s, serr := ecdsa.Sign(rand.Reader, privatekey, signhash)
if serr != nil {
fmt.Println(err)
os.Exit(1)
}
// Verify
verifystatus := ecdsa.Verify(&pubkey, signhash, r, s)
fmt.Println(verifystatus) // should be true
}
AES
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"io"
"strings"
)
func addBase64Padding(value string) string {
m := len(value) % 4
if m != 0 {
value += strings.Repeat("=", 4-m)
}
return value
}
func removeBase64Padding(value string) string {
return strings.Replace(value, "=", "", -1)
}
func Pad(src []byte) []byte {
padding := aes.BlockSize - len(src)%aes.BlockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(src, padtext...)
}
func Unpad(src []byte) ([]byte, error) {
length := len(src)
unpadding := int(src[length-1])
if unpadding > length {
return nil, errors.New("unpad error. This could happen when incorrect encryption key is used")
}
return src[:(length - unpadding)], nil
}
func encrypt(key []byte, text string) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
msg := Pad([]byte(text))
ciphertext := make([]byte, aes.BlockSize+len(msg))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return "", err
}
cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(msg))
finalMsg := removeBase64Padding(base64.URLEncoding.EncodeToString(ciphertext))
return finalMsg, nil
}
func decrypt(key []byte, text string) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
decodedMsg, err := base64.URLEncoding.DecodeString(addBase64Padding(text))
if err != nil {
return "", err
}
if (len(decodedMsg) % aes.BlockSize) != 0 {
return "", errors.New("blocksize must be multipe of decoded message length")
}
iv := decodedMsg[:aes.BlockSize]
msg := decodedMsg[aes.BlockSize:]
cfb := cipher.NewCFBDecrypter(block, iv)
cfb.XORKeyStream(msg, msg)
unpadMsg, err := Unpad(msg)
if err != nil {
return "", err
}
return string(unpadMsg), nil
}
func main() {
key := []byte("LKHlhb899Y09olUi")
encryptMsg, _ := encrypt(key, "test")
msg, _ := decrypt(key, encryptMsg)
fmt.Println(msg) // Hello World
}
RSA
包含 OAEP 與 PKCS
先產生公鑰與私鑰
openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -pubout -out public.pem
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
)
func rsaEncrypt(origData []byte) ([]byte, error) {
block, _ := pem.Decode(publicKey)
if block == nil {
return nil, errors.New("public key error")
}
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
pub := pubInterface.(*rsa.PublicKey)
return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}
func rsaDecrypt(ciphertext []byte) ([]byte, error) {
block, _ := pem.Decode(privateKey)
if block == nil {
return nil, errors.New("private key error")
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}
var privateKey = []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDZyTI4o7pukaJN6sVklkX4sR5IRpLXzPv4/28YVD1xaPn1Q69o
7G6GfHacMtsPZDkEFeGmZBWb4YHLqRczKM3ZPSEA2/FBGZoxKiCq80NMhPngiEWy
gG+J7CyXXO9syHFpSO5AciB0P3r2aewWhVMub9bDa9uwUnMqFCmy65GB/QIDAQAB
AoGARaYZgJGkCr5aeK6vSBbi88C5HYYsagVtQ9l0zwQJzl4zKiPmUhji0/G0AQom
koqLzWmuC4eQfZSl7Nr7x2myQsMxd6W1eZhU/Jki3v/tqG5rDpDz0X0/05uOsZoe
i+6EPhRiT1Y95R2evKpcCwOtUjOD3uQZx6vmytUeEQ7U4sECQQD0rCOdE6OC1LQJ
X2xPqvM9WHeHavhktvCZWkmzfzb/wDtAcbrspS+riBCdiwesP9d7rujmhNUG6vAd
NYVqD4NxAkEA495l33ImdwsyX/IvkastyJ65JDKtS20nHWqzFGW3pVd7liGTvo5k
Iil3vwIM6Mdw/AVUubsEUIvrHC8u2cgJTQJASD9sZL2f0sosP3hF62B3Yu30nbAg
mNzMPvxCNxahjvOci3MJ10cPxH7xKRQct+hCIOuNKkSfAuPs8zMSqjbagQJAUdgI
eRgz7qAL6OBA664zFJLF5tV43tWGrg8r4RCjxHRGhGbs/Q2Bs693PhjLcDRqRWrY
wpkEdLW8rXPY/QnXJQJBAL3uYok6AeKf/UDs1/tR8RqSSWwAQC6FGXbygsLKfywD
v+6/UK1M6tc3S8jHvCZUw5Ybds0KUKMiaATX7RYUDQo=
-----END RSA PRIVATE KEY-----
`)
var publicKey = []byte(`
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZyTI4o7pukaJN6sVklkX4sR5I
RpLXzPv4/28YVD1xaPn1Q69o7G6GfHacMtsPZDkEFeGmZBWb4YHLqRczKM3ZPSEA
2/FBGZoxKiCq80NMhPngiEWygG+J7CyXXO9syHFpSO5AciB0P3r2aewWhVMub9bD
a9uwUnMqFCmy65GB/QIDAQAB
-----END PUBLIC KEY-----
`)
func main() {
data, err := rsaEncrypt([]byte("test"))
if err != nil {
panic(err)
}
decryptedData, err := rsaDecrypt(data)
if err != nil {
panic(err)
}
fmt.Println(string(decryptedData))
}
Last updated