
md5
128bit,中独16字节
如 :md5 (“hello world!”) = fc3ff98e8c6a0d3087d515c0473f8677 // 32位16进制数字
func Test(t *testing.T) { //编制一 str := "hello world!" has := md5.Sum([]byte(str)) md5str1 := fmt.Sprintf("%x",霸加编制 has) //将[]byte转成16进制 t.Log(md5str1) //编制二 w := md5.New() io.WriteString(w, str) md5str2 := fmt.Sprintf("%x", w.Sum(nil)) t.Log(md5str2)}SHA1
160bit,20字节
如 :SHA1 (“hello world!”) = 430ce34d020724ed75a196dfc2ad67c77772d169 // 40位16进制数字
func Test(t *testing.T) { str := "hello world!" //产生发火一个散列值得编制是密算 sha1.New(),sha1.Write(bytes),中独然后 sha1.Sum([]byte{ }) 。霸加编制 h := sha1.New() //写进要措置的密算字节 。 h.Write([]byte(str)) //SHA1 值经常以 16 进制输进,中独比如在 git commit 中。霸加编制 t.Log(hex.EncodeToString(h.Sum(nil)))}RIPEMD-160
160bit ,密算20字节
如 :RIPEMD-160 (“hello world!”) = dffd03137b3a333d5754813399a5f437acd694e5 // 40位16进制数字
func Test(t *testing.T) { str := "hello world!" h := ripemd160.New() h.Write([]byte(str)) t.Log(hex.EncodeToString(h.Sum(nil)))}SHA256
256bit,中独32字节
如:SHA256 (“hello world!”) = 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 // 64位16进制数字
func Test(t *testing.T) { str := "hello world!" // 第一种调用编制 sum := sha256.Sum256([]byte(str)) t.Logf("%x\n",霸加编制 sum) // 第二种调用编制 h := sha256.New() io.WriteString(h,str) t.Log(hex.EncodeToString(h.Sum(nil)))}SHA256完成事理
附加加添⽐特
SHA-256算法输⼊报⽂的最⼤⻓度不超出2^64 bit,输⼊按512bit分组进⾏措置,密算产⽣的中独输进是⼀个256bit的报⽂摘要。
SHA256算法包含以下⼏步:
对报⽂进⾏加添,霸加编制使报⽂⻓度与448 模512 同余(⻓度=448 mod512),密算加添的⽐特数局限是1 到512 ,加添⽐特串的最⾼位为1,此外位为0。就是先在报⽂后⾯加⼀个 1 ,再加良多个0 ,直到⻓度满⾜mod512=448 。为甚么是448,因为448+64=512 。第⼆步会加上⼀个64bit的原始报⽂的 ⻓度信息。附加⻓度值
将⽤64bit 展示的初始报⽂(加添前)的位⻓度附加在法度圭表类型1的下场后(低位字节优先)初始化缓存
使⽤⼀个256bit 的缓存来存放该散列函数的中心及幻想下场下场 。该缓存展示为:
A=0x6A09E667
B=0xBB67AE85
C=0x3C6EF372
D=0xA54FF53A
E=0x510E527F
F=0x9B05688C
G=0x1F83D9AB
H=0x5BE0CD19措置512bit(16 个字)报⽂分组序列
该算法使⽤了六种根本逻辑函数,由64 步迭代运算构成 。每步都以256bit 缓存ABCDEFGH 为输⼊,然后更新缓存内容。每步使⽤⼀个32bit 常数值Kt 和⼀个32bit Wt 。
SHA512
512bit,64字节
如 :SHA512 (“hello world!”) = db9b1cd3262dee37756a09b9064973589847caa8e53d31a9d142ea2701b1b28abd97838bb9a27068ba305dc8d04a45a1fcf079de54d607666996b3cc54f6b67c // 128位16进制数字
func Test(t *testing.T) { str := "hello world!" // 第一种调用编制 sum := sha512.Sum512([]byte(str)) t.Logf("%x\n", sum) // 第二种调用编制 h := sha512.New() io.WriteString(h,str) t.Log(hex.EncodeToString(h.Sum(nil)))}加密一样往常分为对称加密(Symmetric Key Encryption)和非对称加密(Asymmetric Key Encryption)。
对称加密又分为分组加密和序列暗码 。
分组暗码,也叫块加密(block cyphers) ,一次加密明文中的一个块。是将明文按必定的位长分组 ,明文组经由加密运算掉落踪掉落踪密文组,密文组经由解密运算(加密运算的逆运算),恢复成明文组。
序列暗码 ,也叫流加密(stream cyphers),一次加密明文中的一个位。是指独霸多量的密钥(制乱元素)经由过程某种宏壮的运算(暗码算法)产生发火除夜量的伪随机位流 ,用于对明文位流的加密。
解密是指用一样的密钥和暗码算法及与加密不异的伪随机位流 ,用以恢复明文位流。
分组加密算法中,有ECB,CBC,CFB,OFB这几种算法编制。
| 加密编制 | 诠释 |
|---|---|
| ECB | 最根本的加密编制 ,也就是但凡邃晓的加密,不异的明⽂将永远加密成不异的密⽂,⽆初始向量,随便遭到暗码本重放***击击,⼀般气候下很少⽤ |
| CBC | 明⽂被加密前要与前⾯的密⽂进⾏异或运算后再加密 ,是以只需选择不合的初始向量,不异的密⽂加密后会构成不合的密⽂,这是⽬前应⽤最⼴泛的编制 。CBC加密后的密⽂是凹凸⽂相干的,但明⽂的偏向不会传递到后续分组 ,但假定⼀个分组丢损掉落踪落,后⾯的分组将全数消弭(同步偏向) |
| CFB | 近似于⾃同步序列暗码,分组加密后 ,按8位分组将密⽂和明⽂进⾏移位异或后掉落踪掉落踪输进同时回响回移位存放器,益处最⼩可以按字节进⾏加解密,也可所以n位的 ,CFB也是凹凸⽂相干的 ,CFB编制下,明⽂的⼀个偏向会影响后⾯的密⽂(偏向分散)。 |
| OFB | 将分组暗码作为同步序列暗码运⾏,和CFB近似,不过OFB⽤的是前⼀个n位密⽂输进分组回响回移位存放器 ,OFB没有偏向分散问题 |
最经常独霸的对称加密算法DES 、3DES(TripleDES)和AES,常采取的加添⽅式是NoPadding(不加添)、Zeros加添(0加添)、PKCS5Padding加添。
加密算法请求明文需求按必定长度对齐 ,叫做块大年夜小(BlockSize) ,比如8字节 ,那么对一段肆意的数据 ,加密前需求对末尾一个块加添到8 字节,解密后需求删除损掉落踪落加添的数据 。
| 加添⽅式 | 诠释 |
|---|---|
| ZeroPadding | 数据长度舛错齐时独霸0加添,不然不加添 |
| PKCS7Padding | 假天命据长度需求加添n(n>0)个字节才对齐,那么加添n个字节 ,每个字节都是n;假天命据本身就已对齐了 ,则加添一块长度为块大年夜小的数据,每个字节都是块大年夜小 |
| PKCS5Padding | PKCS7Padding的子集,块大年夜小结实为8字节 |
因为独霸PKCS7Padding/PKCS5Padding加添时,末尾一个字节必定为加添数据的长度,所以在解密后可以切确删除加添的数据,而独霸ZeroPadding加添时 ,没编制分辨真实数据与加添数据,所以只契合以\0末尾的字符串加解密 。
对称加密需求的加添函数
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) // 往损掉落踪落末尾⼀个字节 unpadding 次 unpadding := int(data[length-1]) return data[:(length - unpadding)]}func ZeroPadding(data []byte, blockSize int) []byte { padding := blockSize - len(data)%blockSize padtext := bytes.Repeat([]byte{ 0}, padding) return append(data, padtext...)}func ZeroUnPadding(data []byte) []byte { return bytes.TrimRightFunc(data, func(r rune) bool { return r == rune(0) })}DES
//DES加密字节数组,前去字节数组func DesEncrypt(originalBytes, key []byte) ([]byte, error) { block, err := des.NewCipher(key) if err != nil { return nil, err } originalBytes = PKCS5Padding(originalBytes, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, key) cipherArr := make([]byte, len(originalBytes)) blockMode.CryptBlocks(cipherArr, originalBytes) return cipherArr, nil}//DES解密字节数组 ,前去字节数组func DesDecrypt(cipherBytes, key []byte) ([]byte, error) { block, err := des.NewCipher(key) if err != nil { return nil, err } blockMode := cipher.NewCBCDecrypter(block, key) originalText := make([]byte, len(cipherBytes)) blockMode.CryptBlocks(originalText, cipherBytes) originalText = PKCS5UnPadding(originalText) return originalText, nil}//DES加密⽂本
,前去加密后⽂本func DesEncryptString(originalText string, key []byte) (string, error) { cipherArr, err := DesEncrypt([]byte(originalText), key) if err != nil { return "", err } base64str := base64.StdEncoding.EncodeToString(cipherArr) return base64str, nil}//对加密⽂本进⾏DES解密
,前去解密后明⽂func DesDecryptString(cipherText string, key []byte) (string, error) { cipherArr, _ := base64.StdEncoding.DecodeString(cipherText) cipherArr, err := DesDecrypt(cipherArr, key) if err != nil { return "", err } return string(cipherArr), nil}3DES
// 3DES加密字节数组,前去字节数组func TripleDesEncrypt(originalBytes, key []byte) ([]byte, error) { block, err := des.NewTripleDESCipher(key) if err != nil { return nil, err } originalBytes = PKCS5Padding(originalBytes, block.BlockSize()) // originalBytes = ZeroPadding(originalBytes, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, key[:8]) cipherArr := make([]byte, len(originalBytes)) blockMode.CryptBlocks(cipherArr, originalBytes) return cipherArr, nil}// 3DES解密字节数组,前去字节数组func TripleDesDecrypt(cipherBytes, key []byte) ([]byte, error) { block, err := des.NewTripleDESCipher(key) if err != nil { return nil, err } blockMode := cipher.NewCBCDecrypter(block, key[:8]) originalArr := make([]byte, len(cipherBytes)) blockMode.CryptBlocks(originalArr, cipherBytes) originalArr = PKCS5UnPadding(originalArr) // origData = ZeroUnPadding(origData) return originalArr, nil}// 3DES加密字符串 ,前去base64措置后字符串func TripleDesEncrypt2Str(originalText string, key []byte) (string, error) { block, err := des.NewTripleDESCipher(key) if err != nil { return "", err } originalData := PKCS5Padding([]byte(originalText), block.BlockSize()) // originalData = ZeroPadding(originalData, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, key[:8]) cipherArr := make([]byte, len(originalData)) blockMode.CryptBlocks(cipherArr, originalData) cipherText := base64.StdEncoding.EncodeToString(cipherArr) return cipherText, nil}// 3DES解密base64措置后的加密字符串 ,前去明⽂字符串func TripleDesDecrypt2Str(cipherText string, key []byte) (string, error) { cipherArr, _ := base64.StdEncoding.DecodeString(cipherText) block, err := des.NewTripleDESCipher(key) if err != nil { return "", err } blockMode := cipher.NewCBCDecrypter(block, key[:8]) originalArr := make([]byte, len(cipherArr)) blockMode.CryptBlocks(originalArr, cipherArr) originalArr = PKCS5UnPadding(originalArr) // origData = ZeroUnPadding(origData) return string(originalArr), nil}AES
//AES加密字节数组,前去字节数组func AesEncrypt(originalBytes, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() originalBytes = PKCS5Padding(originalBytes, blockSize) // originalBytes = ZeroPadding(originalBytes, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) cipherBytes := make([]byte, len(originalBytes)) // 屈就CryptBlocks⽅法的声明
,以下⽅式初始化crypted也可以 // crypted := originalBytes blockMode.CryptBlocks(cipherBytes, originalBytes) return cipherBytes, nil}//AES解密字节数组,前去字节数组func AesDecrypt(cipherBytes, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) originalBytes := make([]byte, len(cipherBytes)) // origData := cipherBytes blockMode.CryptBlocks(originalBytes, cipherBytes) originalBytes = PKCS5UnPadding(originalBytes) // origData = ZeroUnPadding(origData) return originalBytes, nil}//AES加密⽂本,前去对加密后字节数组进⾏base64措置后字符串func AesEncryptString(originalText string, key []byte) (string, error) { cipherBytes, err := AesEncrypt([]byte(originalText), key) if err != nil { return "", err } base64str := base64.StdEncoding.EncodeToString(cipherBytes) return base64str, nil}//AES解密⽂本 ,对Base64措置后的加密⽂本进⾏AES解密
,前去解密后明⽂func AesDecryptString(cipherText string, key []byte) (string, error) { cipherBytes, _ := base64.StdEncoding.DecodeString(cipherText) cipherBytes, err := AesDecrypt(cipherBytes, key) if err != nil { return "", err } return string(cipherBytes), nil}RSA算法也是一个块加密算法( block cipher algorithm),老是在一个结实长度的块前程行独霸。但跟AES等不合的是,block length是跟key length有关的 。
每次RSA加密的明文的长度是受RSA加添编制限制的 ,可是RSA每次加密的块长度就是key length。
| 加添⽅式 | 密文长度 |
|---|---|
| PKCS1Padding | 必须 比 RSA 秘钥模长(modulus) 短起码11个字节, 也就是RSA_SIZE(rsa) – 11 |
| OAEPPadding | RSA_SIZE(rsa) – 41 |
| NOPadding | 可以和RSA钥模长一样长 ,假定输进的明文太长 ,必须切割 , 然后加添 |
在不合的padding编制下,独霸不异长度的密钥可以加密的数据最除夜长度不合在不合密钥长度下,独霸不异的padding编制可以加密的数据最除夜长度也不合
是以,离开了密钥长度而构和padding编制可以加密的最除夜长度是不严谨的 。经常独霸的密钥长度有1024bits,2048bits等,幻想上1024bits的密钥可以加密的数据最除夜长度为1024bits(即1024/8 = 128bytes) 。2048bits的密钥可以加密的数据最除夜长度为2048bits(2048/8 = 256bytes) ,可是RSA在理论独霸中不成能独霸这类“教科书式的RSA”琐细 。理论独霸中RSA经常与加添技能(padding)一同独霸,可以添加RSA的安然性。
PKCS1
// 加密字节数组
,前去字节数组func RsaEncrypt(publicKey, origData []byte) ([]byte, error) { block, _ := pem.Decode(publicKey) if block == nil { return nil, errors.New("public key error") } pubInte***ce, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } pub := pubInte***ce.(*rsa.PublicKey) return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)}// 解密字节数组,前去字节数组func RsaDecrypt(privateKey, 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)}// 加密字符串
,前去base64措置的字符串func RsaEncryptString(publicKey []byte, origData string) (string, error) { block, _ := pem.Decode(publicKey) if block == nil { return "", errors.New("public key error") } pubInte***ce, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return "", err } pub := pubInte***ce.(*rsa.PublicKey) cipherArr, err := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte(origData)) if err != nil { return "", err } else { return base64.StdEncoding.EncodeToString(cipherArr), nil }}// 解密经由base64措置的加密字符串,前去加密前的明⽂func RsaDecryptString(privateKey []byte, cipherText string) (string, error) { block, _ := pem.Decode(privateKey) if block == nil { return "", errors.New("private key error!") } priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return "", err } cipherArr, _ := base64.StdEncoding.DecodeString(cipherText) originalArr, err := rsa.DecryptPKCS1v15(rand.Reader, priv, cipherArr) if err != nil { return "", err } else { return string(originalArr), nil }}OAEP
// 加密func EncryptOAEP(publicKey []byte, text string) (string, error) { block, _ := pem.Decode(publicKey) if block == nil { return "", errors.New("public key error") } pubInte***ce, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return "", err } pub := pubInte***ce.(*rsa.PublicKey) secretMessage := []byte(text) rng := rand.Reader cipherdata, err := rsa.EncryptOAEP(sha1.New(), rng, pub, secretMessage, nil) if err != nil { return "", err } ciphertext := base64.StdEncoding.EncodeToString(cipherdata) return ciphertext, nil}// 解密func DecryptOAEP(privateKey []byte, ciphertext string) (string, error) { block, _ := pem.Decode(privateKey) if block == nil { return "", errors.New("private key error!") } priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return "", err } cipherdata, _ := base64.StdEncoding.DecodeString(ciphertext) rng := rand.Reader plaintext, err := rsa.DecryptOAEP(sha1.New(), rng, priv, cipherdata, nil) if err != nil { return "", err } return string(plaintext), nil}椭圆曲线暗码学(Elliptic curve cryptography,缩写为 ECC) ,是基于椭圆曲线数学幻想完成的⼀种⾮对称加密算法 。
ECC与RSA算法的优势对⽐
椭圆曲线公钥琐细是庖代RSA的强有⼒的竞争者 。
与经典的RSA、DSA等公钥暗码琐细编制相⽐,椭圆暗码琐细编制有以下益处:
(1)安然功用更⾼(ECC可使⽤更短的密钥):
160位ECC加密算法的安然强度相当于1024位RSA加密;
210位ECC加密算法的安然强度相当于2048位RSA加密 。
(2)措置速度快:筹算劲⼩ ,措置速度快 在私钥的措置速度上(解密和签名) ,ECC远 ⽐RSA 、DSA快良多。
(3)存储空间占⽤⼩: ECC的密钥尺⼨和琐细参数与RSA、DSA相⽐要⼩良多 , 所以占⽤的存储空间⼩良多。
(4)带宽请求低使得ECC具有⼴泛的应⽤前景 。ECC的这些特点使它必将庖代RSA,成为通⽤的公钥加密算法 。
//生成ECC椭圆曲线密钥对func GenerateECCKey() (*ecdsa.PublicKey, *ecdsa.PrivateKey, error) { privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) if err != nil { return nil, nil, err } publicKey := &privateKey.PublicKey return publicKey, privateKey, nil}//对消息的散列值生成数字签名func SignECC(msg []byte) ([]byte, []byte) { //掉落踪掉落踪私钥 _, privateKey, err := GenerateECCKey() if err != nil { panic(err) } //筹算哈希值 hash := sha256.New() //填进数据 hash.Write(msg) b := hash.Sum(nil) //对哈希值生成数字签名 r, s, err := ecdsa.Sign(rand.Reader, privateKey, b) if err != nil { panic(err) } rtext, _ := r.MarshalText() stext, _ := s.MarshalText() return rtext, stext}//验证数字签名func VerifySignECC(msg []byte, rtext, stext []byte) bool { //掉落踪掉落踪公钥 publicKey, _, err := GenerateECCKey() if err != nil { panic(err) } //筹算哈希值 hash := sha256.New() hash.Write(msg) b := hash.Sum(nil) //验证数字签名 var r, s big.Int if err := r.UnmarshalText(rtext); err != nil { panic(err) } if err := s.UnmarshalText(stext); err != nil { panic(err) } verify := ecdsa.Verify(publicKey, b, &r, &s) return verify}//测试func Test(t *testing.T) { //模仿发送者 //要发送的消息 msg := []byte("hello world") //生成数字签名 rtext, stext := SignECC(msg) //模仿领受者 //领遭到的消息 acceptmsg := []byte("hello world") //领遭到的签名 acceptrtext := rtext acceptstext := stext //验证签名 verifySignECC := VerifySignECC(acceptmsg, acceptrtext, acceptstext) fmt.Println("验证下场:", verifySignECC)}数字签名的定见
1、签名不成虚构性;
2、签名不成狡赖的;
3、签名可托性 ,签名的辨认和应⽤绝对随便,任何⼈都可以验证签名的有效
性;
4 、签名是不成复制的,签名与原⽂是不成豆割的集团;
5、签名消息不成修改,因为肆意⽐特数据被修改,其签名便被随之改削 ,那么
任何⼈可以验证⽽回尽领受此签名
。
椭圆曲线数字签名算法ECDSA
//⽣成私钥和公钥,⽣成的私钥为筹划体ecdsa.PrivateKey的指针func NewKeyPair() (ecdsa.PrivateKey, []byte) { //⽣成secp256椭圆曲线 curve := elliptic.P256() //产⽣的是⼀个筹划体指针
,筹划体圭表类型为ecdsa.PrivateKey private, err := ecdsa.GenerateKey(curve, rand.Reader) if err != nil { log.Panic(err) } fmt.Printf("私钥:%x\n", private) fmt.Printf("私钥X:%x\n", private.X.Bytes()) fmt.Printf("私钥Y
:%x\n", private.Y.Bytes()) fmt.Printf("私钥D:%x\n", private.D.Bytes()) //x坐标与y坐标拼接在⼀起,⽣成公钥 pubKey := append(private.X.Bytes(), private.Y.Bytes()...) //打印公钥
,公钥⽤16进制打印出来⻓度为128,包含了x轴坐标与y轴坐标 。 fmt.Printf("公钥:%x \n", pubKey) return *private, pubKey}//⽣成签名的DER格式func MakeSignatureDerString(r, s string) string { // 掉落踪掉落踪R和S的⻓度 lenSigR := len(r) / 2 lenSigS := len(s) / 2 // 筹算DER序列的总⻓度 lenSequence := lenSigR + lenSigS + 4 // 将10进制⻓度转16进制字符串 strLenSigR := DecimalToHex(int64(lenSigR)) strLenSigS := DecimalToHex(int64(lenSigS)) strLenSequence := DecimalToHex(int64(lenSequence)) // 凑合DER编码 derString := "30" + strLenSequence derString = derString + "02" + strLenSigR + r derString = derString + "02" + strLenSigS + s derString = derString + "01" return derString}func DecimalToHex(n int64) string { if n < 0 { log.Println("Decimal to hexadecimal error: the argument must be greater than zero.") return "" } if n == 0 { return "0" } hex := map[int64]int64{ 10: 65, 11: 66, 12: 67, 13: 68, 14: 69, 15: 70} s := "" for q := n; q > 0; q = q / 16 { m := q % 16 if m > 9 && m < 16 { m = hex[m] s = fmt.Sprintf("%v%v", string(m), s) continue } s = fmt.Sprintf("%v%v", m, s) } return s}//验证签名1func VerifySig(pubKey, message []byte, r, s *big.Int) bool { curve := elliptic.P256() //公钥的⻓度 keyLen := len(pubKey) //前⼀半为x轴坐标,后⼀半为y轴坐标 x := big.Int{ } y := big.Int{ } x.SetBytes(pubKey[:(keyLen / 2)]) y.SetBytes(pubKey[(keyLen / 2):]) rawPubKey := ecdsa.PublicKey{ curve, &x, &y} //屈就生意哈希、公钥
、数字签名验证成功。ecdsa.Verify func Verify(pub *PublicKey, hash[] byte, r * big.Int, s * big.Int) bool res := ecdsa.Verify(&rawPubKey, message, r, s) return res}//验证签名2func VerifySignature(pubKey, message []byte, r, s string) bool { curve := elliptic.P256() //公钥的⻓度 keyLen := len(pubKey) //前⼀半为x轴坐标
,后⼀半为y轴坐标 x := big.Int{ } y := big.Int{ } x.SetBytes(pubKey[:(keyLen / 2)]) y.SetBytes(pubKey[(keyLen / 2):]) rawPubKey := ecdsa.PublicKey{ curve, &x, &y} //屈就生意哈希、公钥
、数字签名验证成功 。ecdsa.Verify func Verify(pub *PublicKey, hash[] byte, r * big.Int, s * big.Int) bool rint := big.Int{ } sint := big.Int{ } rByte, _ := hex.DecodeString(r) sByte, _ := hex.DecodeString(s) rint.SetBytes(rByte) sint.SetBytes(sByte) //fmt.Println("------", rint.SetBytes(rByte)) //fmt.Println("------", sint.SetBytes(sByte)) res := ecdsa.Verify(&rawPubKey, message, &rint, &sint) return res}//验证过程func Test(t *testing.T) { //1 、⽣成签名 fmt.Println("1
、⽣成签名-------------------------------") //调⽤函数⽣成私钥与公钥 privKey, pubKey := NewKeyPair() //信息的哈希 msg := sha256.Sum256([]byte("hello world")) //屈就私钥和信息的哈希进⾏数字签名
,产⽣r和s r, s, _ := ecdsa.Sign(rand.Reader, &privKey, msg[:]) //⽣成r
、s字符串 fmt.Println("-------------------------------") strSigR := fmt.Sprintf("%x", r) strSigS := fmt.Sprintf("%x", s) fmt.Println("r、s的10进制分袂为:", r, s) fmt.Println("r、s的16进制分袂为:", strSigR, strSigS) //r和s拼接在⼀起 ,构成数字签名的der格式 signatureDer := MakeSignatureDerString(strSigR, strSigS) //打印数字签名的16进制展示 fmt.Println("数字签名DER格式为
:", signatureDer) fmt.Println() //2 、签名验证过程 fmt.Println("2、签名验证过程-------------------------------") res := VerifySig(pubKey, msg[:], r, s) fmt.Println("签名验证下场
:", res) res = VerifySignature(pubKey, msg[:], strSigR, strSigS) fmt.Println("签名验证下场
:", res)}Base64
Base64就是⼀种基于64个可打印字符来展示⼆进制数据的⽅法。Base64使⽤了26个⼩写字⺟、26个⼤写字⺟、10个数字和两个标识表记标帜(比如“+”和“/”),⽤于在电⼦邮件多么的基于⽂本的序言中传输⼆进制数据。
Base64字符集:
将每个字符转成ASCII编码(10进制)将10进制编码转成2进制编码将2进制编码屈就6位⼀组进⾏等分将6位⼀组的2进制数⾼位补零,然后转成10进制数将10进制数作为索引 ,从Base64编码表中查找字符每3个字符的⽂本将编码为4个字符⻓度(38=46)
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
Base64的法度圭表类型
a. 若⽂本为3个字符 ,则正好编码为4个字符⻓度;
b. 若⽂本为2个字符 ,则编码为3个字符,因为不⾜4个字符 ,则在尾部⽤⼀个“=”补⻬;
c. 若⽂本为1个字符 ,则编码为2个字符,因为不⾜4个字符,则在尾部⽤两个“=”补⻬ 。
从别人的工作中接收经验来阻拦本身的偏向几回 ,正如我们是站在巨人的肩膀上才调做出更好的下场 。
https://github.com/rubyhan1314/Golang-100-Days
https://blog.csdn.net/luckydog612/article/details/80547758
https://www.cnblogs.com/yanzi-meng/p/9640578.html
https://www.cnblogs.com/starwolf/p/3365834.html
https://blog.csdn.net/u013073067/article/details/87086562
https://www.cnblogs.com/Terry-Wu/p/10314315.html
http://blog.studygolang.com/2013/01/go%E5%8A%A0%E5%AF%86%E8%A7%A3%E5%AF%86%E4%B9%8Bdes/
https://blog.csdn.net/kikajack/article/details/78329567
到此这篇关于Go中独霸加密算法的编制的文章就引见到这了,更多相干go 加密算法内容请搜刮完竣下载之前的文章或延续不雅不雅不雅不雅鉴赏上面的相干文章希看大年夜师往后多多支撑完竣下载 !
本文由作文网时尚栏目发布,感谢您对作文网的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人站长或者朋友圈,但转载请说明文章出处“Go中独霸加密算法的编制”
