动态密码算法介绍与实现

算法种类

根据技术特征,现代密码学可分为三类:

对称算法

说明:加密密钥和解密密钥相同,对明文、密文长度没有限制

子算法:

  • 流密码算法:每次加密或解密一位或一字节的明文或密文
  • 分组密码算法:将明文(密文)分成固定长度的数据块(比特块或字节块),用同一密钥和算法对每一明文(密文)块加密(解密)后得到等长的密文(明文)块,然后将密文(明文)块按照顺序组合起来最终得到密文(明文)

常见算法:

  • 流密码算法:RC4
  • 分组密码算法:DES、IDEA、RC2、AES、SM4

非对称算法

说明:加密密钥和解密密钥不相同。

  • 公钥加密,私钥解密
  • 私钥加签,公钥验签

常见算法:RSA、DH、DSA、ECDSA、ECC、SM2

摘要算法

说明:把任意长的输入消息数据转化成固定长度的输出数据的一种密码算法,又称散列函数、哈希函数或杂凑函数、单向函数等。摘要算法没有密钥。

常见算法:MD5、SHA1、SM3

实战

对称算法-RC4

说明

1.加密key长度为1byte~256byte

2.加密后的结果为base-16编码的字符串,需进行转换

代码

package mainimport ( "crypto/rc4" "fmt")func RC4() { //加密 var key []byte = []byte("fd6cde7c2f4913f22297c948dd530c84") //初始化用于加密的KEY,长度1byte~256byte rc4obj1, _ := rc4.NewCipher(key)                            //返回 Cipher rc4str1 := []byte("RC4")                                    //需要加密的字符串 plaintext := make([]byte, len(rc4str1)) rc4obj1.XORKeyStream(plaintext, rc4str1)     //加密 stringinf1 := fmt.Sprintf("%xn", plaintext) //转换字符串,base-16 编码的字符串,每个字节使用 2 个字符表示 fmt.Println("RC4加密后:" + stringinf1) //解密 dest2 := make([]byte, len(rc4str1)) cipher2, _ := rc4.NewCipher(key) // 切记:这里不能重用rc4obj1,必须重新生成新的 cipher2.XORKeyStream(dest2, plaintext) fmt.Printf("RC4解密后:%s nn", dest2)}func main() { RC4()}

结果:可以看到长度是一致的

➜ myproject go run main.go

RC4加密后:4daff0

RC4解密后:RC4

对称算法-AES

说明

1.AES是分组密码算法,所以AES的计算包含两部分

  • 分组大小:128位
  • 密钥大小:128位、192位和256位,三种可选

常用密码算法介绍

2.AES加密过程是在一个4×4的字节(128位)矩阵上运作,加密时,各轮AES加密循环(除最后一轮外)均包含4个步骤

  • AddRoundKey:—矩阵中的每一个字节都与该次回合金钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
  • SubBytes:通过一个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
  • ShiftRows:将矩阵中的每个横列进行循环式移位。
  • MixColumns:使用线性转换来混合每内联的四个字节

工作模式

AES有6种加密模式。ECB模式和CBC模式是最常用的两种模式,代码也只实现这两种。

需要块对对齐(填充)的AES加密模式:ECB、CBC、PCBC,其余模式无需块对齐。

需要初始向量的AES加密模式:除ECB模式外,都需要初始向量。

电子密码本:Electronic Code Book Mode (ECB)

ECB模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。

优点:有利于并行计算;误差不会累计(互不干扰)。

缺点:可能对明文进行主动攻击。

常用密码算法介绍

密码分组链接:Cipher Block Chaining Mode (CBC)

CBC模式对于每个待加密的密码块,在加密前会先与前一个密码块的密文异或然后再用加密器加密(图中的圆圈十字符号表示异或操作,下同)。第一个明文块与一个叫初始化向量(IV)的数据块异或。加、解密双方共同知晓密钥和初始化向量才能实现加解密。

优点:安全性比ECB模式高;是SSL的标准。

缺点:数据块之间的加密有依赖关系,因此不能并行计算。

常用密码算法介绍

密文反馈:Cipher Feedback Mode (CFB)

CFB 模式是用分组算法实现流算法,明文数据不需要按分组大小对齐。

优点:明文数据不需要按分组大小对齐,即无需填充。

缺点:同CBC模式,无法并行计算。

常用密码算法介绍

输出反馈:Output Feedback Mode (OFB)

OFB 模式的过程和CBC模式有点像,但明文数据不需要按分组大小对齐。

优点:明文数据不需要按分组大小对齐,即无需填充。

缺点:同CBC模式,无法并行计算。

常用密码算法介绍

计数器模式:Counter Mode (CTR)

CTR模式是在ECB模式的基础上,引入了Nonce随机数和Counter计数器,Nounce随机数和Counter计数器整体可看作计数器,每加密一段明文,计数器向上加一,并且这个计数器都会和初始IV进行连接、加加、异或等运算,然后使用加密器进行加密,最后在和明文异或得到分段密文。

优点:明文数据不需要按分组大小对齐,即无需填充。

缺点:加密方和解密方需要同时维护初始IV、Nonce、Counter。

常用密码算法介绍

填充密码分组链接:Propagating Cipher Block Chaining Mode(PCBC)

PCBC模式是CBC模式的改进版,与CBC模式的不同点在于,CBC模式后段明文加密的所需向量是前一段的密文,而PCBC模式后段明文加密所需的向量是前一段明文和密文的异或值。

优点:同CBC模式。

缺点:同CBC模式。

常用密码算法介绍常用密码算法介绍

代码

////////////////////////////////AESfunc AES() { origData := []byte("AES待加密数据")    // 待加密的数据 key := []byte("ABCDEFGHIJKLMNOP") // 加密的密钥,只能128位、192位和256位 fmt.Println("原文:", string(origData)) fmt.Println("------------------ CBC模式 --------------------") encrypted := AesEncryptCBC(origData, key) fmt.Println("密文(hex):", hex.EncodeToString(encrypted)) fmt.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted)) decrypted := AesDecryptCBC(encrypted, key) fmt.Println("解密结果:", string(decrypted)) fmt.Println("------------------ ECB模式 --------------------") encrypted = AesEncryptECB(origData, key) fmt.Println("密文(hex):", hex.EncodeToString(encrypted)) fmt.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted)) decrypted = AesDecryptECB(encrypted, key) fmt.Println("解密结果:", string(decrypted))}// =================== CBC ======================func AesEncryptCBC(origData []byte, key []byte) (encrypted []byte) { // 分组秘钥 // NewCipher该函数限制了输入k的长度必须为16, 24或者32 block, _ := aes.NewCipher(key) blockSize := block.BlockSize()                              // 获取秘钥块的长度 origData = pkcs5Padding(origData, blockSize)                // 补全码 blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 加密模式,key[:blockSize]是IV 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)]}// =================== ECB ======================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() { AES()}

结果:

➜ myproject go run main.go

原文:AES待加密数据

—————— CBC模式 ——————–

密文(hex):49c5e79d2c1167345135323346135484a2ad8e591b05b75ac0d5fcc206fdda90

密文(base64):ScXnnSwRZzRRNTIzRhNUhKKtjlkbBbdawNX8wgb92pA=

解密结果:AES待加密数据

—————— ECB模式 ——————–

密文(hex):74c3a459214e98d6e91ffc4ea291d63ece558f39d07e3f4ade14adbc3486f60f

密文(base64):dMOkWSFOmNbpH/xOopHWPs5VjznQfj9K3hStvDSG9g8=

解密结果:AES待加密数据

非对称算法-RSA

说明

1.加密的明文长度不能超过 RSA密钥的长度,根据填充方案的不同,RSA加密时,对于原文数据的要求

  • OAEP填充模式:原文长度 <= 密钥模长 – (2 * 原文的摘要值长度) – 2字节 ,各摘要值长度:
  • SHA-1: 20字节 SHA-256: 32字节 SHA-384: 48字节 SHA-512: 64字节
  • PKCA1-V1_5填充模式:原文长度 <= 密钥模长 – 11字节,比如密钥长度1024位(即128字节),明文长度不能超过117=128-11

2.RSA加密内容的长度有限,这是它的算法决定的,所以一般用RSA加密其他算法的密钥,比如用RSA加密AES的密钥,再用AES算法加密明文数据。如果非要加密大量数据,只能将数据分段进行加密。

3.RSA一般还是用来签名比较多,如果只是签名用的话,加密明文的MD5值就可以

4.密文的长度总是密钥的长度的一半

5.RSA签名也需要选择填充方案,如PKCS_V15或PKCS_V21(PSS)

6.RSA签名先计算出消息的消息摘要,然后使用自己的私钥加密消息摘要,所以需要选择计算摘要的算法,如SHA256等

样式

密钥生成有几种方案,我们用openssl生成密钥对,看看公私钥的样式

生成RSA私钥(无加密)

openssl genrsa -out rsa_private.key 2048#查看rsa_private.key-----BEGIN RSA PRIVATE KEY-----MIIEpAIBAAKCAQEA3vK7hHEblXqIw4OlAdyYBoSm6TYW80KH6WenPR24J8FehpxByQY6mpMTR/XM4BTAflfouvdNZ9OPAm3IarHaBbc1aXwznzn93yPp/nQdBdZq9RDAJA1f5ESrCY/YJWiBW88C33EtLF2xiOj1l+02HepdFo0FvO0BE19yrS2mcBLH8LTUYAW+7dUzjonS1hTKJo+i1r+Zwq6Djp7mxB6hFqsRSIVVypFd6gs2o4GLUJRR9CQLYoceSFECsRef25jhKFxR/HaMZJPHkMo9W8CNV7swLatDcObv8AJC7vHmjYVQDSxbQMxtK+8fUYGMwS4TLHnt/IL0tbyQWuvh1f6LaQIDAQABAoIBAEQCl+FW/6shrga2aeefe2DBpokNzwJ2ES/KRuIF5t95xXQaxpakJ8xvgTo6aT0SF4ZzGrOuLRa3GrEK/FBP4MpNkSWUlcrEzgT7162fjhrxxb7sVTCqQ85GhEZucuk2b/+prp6qz7Tw/+9b4U9vNUr661qtukpfoixeuYTKoDMfdbPG+nMIVlHb5jRfH/foLarau4Y+8DNr+OTW73ay84i0n8CwdI4uLAAHF1MskdSKfLFn1QcmFBjFspXNqnyQo3W1LFvyoLy2v7rtQGh3oFlug0p8EguurW4Hmgcfsobyo6Lz4INM5WqNJ7qiltMBRkkrievhO/IjL8UIc4MC94ECgYEA99aYQXVk4mFCF6DNqYa28feHwmCIl1x76ylVC+k3oOcoH1SLaX4ahZbQKAGLgi3tGZ/BedYBKi/6Yv5DdljSR4XKD0fipl7LKvF1uHLk7JzdL87RdlvEmB0E3oOewzu+T5d4t3SiSU4yQqaCFOxX8s+NqV5HostI0MdUFjDoMWUCgYEA5kpNJ1Pm6fDWAJLNNqPGrDKcb93ahmpYIsh0G6DJklJxHVHpdx+poLkEduN5MtCK7jcHaoguUyzNuD1TY9+mVLakQ4KzspsL9ggqecXSmkM7D1BqL1OdJ9JPjJeo3CPrikYSqSKONzwNjmfekNuYpTKXaEZmPrdYX0d5+mqCs7UCgYEAwKFAshAGm5WwgyDu+QbGBwe3szLIt6ygfEUh3yIjpKJGIyPZP+NNxetUWuPohQQhNztea84UFbA40tyBnuimeATa6kmbNmiTTQtjzjsvB2Fc4Z3EXFQzV2+mqzRu***MVKk6kCgYEAh6od6Z0z231VlODmo9m3oJnwLrazlZvwcA1G2T/Pf7Oxj2RB9Tth4p0cVC2NqLHSJqOkas3u/HDYgEEgbyXCBwXRnzPQSNeuJDKLU1GGz/nrQQpOg7LuUhdDZb+yan1+tOay95Cz1zY5hjsKkqvLMQasy3EtqqS4GukwoqU8ekECgYBzq/iL6f+h1MyHrPfsrgLDogb2pwM9lXLV1dj+Z5mU2EFnGV3tP+OlJRC0VZsVy4XsmjUbBVHc2AUB8xAqzpsurjSPYPk8bY0LpRCF95cIiz6296cUIdn395fH9Or7v/5BoXK9twG340j/ETxkLUh70ZZ7Vm0J4o8wNZZjVQb8lg==-----END RSA PRIVATE KEY-----

生成RSA公钥

本质上是从私钥中提取公钥

openssl rsa -in rsa_private.key -pubout -out rsa_public.key#查看rsa_public.key-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3vK7hHEblXqIw4OlAdyYBoSm6TYW80KH6WenPR24J8FehpxByQY6mpMTR/XM4BTAflfouvdNZ9OPAm3IarHaBbc1aXwznzn93yPp/nQdBdZq9RDAJA1f5ESrCY/YJWiBW88C33EtLF2xiOj1l+02HepdFo0FvO0BE19yrS2mcBLH8LTUYAW+7dUzjonS1hTKJo+i1r+Zwq6Djp7mxB6hFqsRSIVVypFd6gs2o4GLUJRR9CQLYoceSFECsRef25jhKFxR/HaMZJPHkMo9W8CNV7swLatDcObv8AJC7vHmjYVQDSxbQMxtK+8fUYGMwS4TLHnt/IL0tbyQWuvh1f6LaQIDAQAB-----END PUBLIC KEY-----

查看公/私钥明细

openssl rsa -in rsa_private.key -noout -textopenssl rsa -pubin -in rsa_public.key -noout -text#私钥明细Private-Key: (2048 bit)modulus:    00:de:f2:bb:84:71:1b:95:7a:88:c3:83:a5:01:dc:    98:06:84:a6:e9:36:16:f3:42:87:e9:67:a7:3d:1d:   b8:27:c1:5e:86:9c:41:c9:06:3a:9a:93:13:47:f5:    cc:e0:14:c0:7e:57:e8:ba:f7:4d:67:d3:8f:02:6d:   c8:6a:b1:da:05:b7:35:69:7c:33:9f:39:fd:df:23:   e9:fe:74:1d:05:d6:6a:f5:10:c0:24:0d:5f:e4:44:    ab:09:8f:d8:25:68:81:5b:cf:02:df:71:2d:2c:5d:   b1:88:e8:f5:97:ed:36:1d:ea:5d:16:8d:05:bc:ed:    01:13:5f:72:ad:2d:a6:70:12:c7:f0:b4:d4:60:05:   be:ed:d5:33:8e:89:d2:d6:14:ca:26:8f:a2:d6:bf:    99:c2:ae:83:8e:9e:e6:c4:1e:a1:16:ab:11:48:85:    55:ca:91:5d:ea:0b:36:a3:81:8b:50:94:51:f4:24:   0b:62:87:1e:48:51:02:b1:17:9f:db:98:e1:28:5c:    51:fc:76:8c:64:93:c7:90:ca:3d:5b:c0:8d:57:bb:    30:2d:ab:43:70:e6:ef:f0:02:42:ee:f1:e6:8d:85:    50:0d:2c:5b:40:cc:6d:2b:ef:1f:51:81:8c:c1:2e:    13:2c:79:ed:fc:82:f4:b5:bc:90:5a:eb:e1:d5:fe:   8b:69publicExponent: 65537 (0x10001)privateExponent:    44:02:97:e1:56:ff:ab:21:ae:06:b6:69:e7:9f:7b:    60:c1:a6:89:0d:cf:02:76:11:2f:ca:46:e2:05:e6:   df:79:c5:74:1a:c6:96:a4:27:cc:6f:81:3a:3a:69:   3d:12:17:86:73:1a:b3:ae:2d:16:b7:1a:b1:0a:fc:    50:4f:e0:ca:4d:91:25:94:95:ca:c4:ce:04:fb:d7:   ad:9f:8e:1a:f1:c5:be:ec:55:30:aa:43:ce:46:84:    46:6e:72:e9:36:6f:ff:a9:ae:9e:aa:cf:b4:f0:ff:   ef:5b:e1:4f:6f:35:4a:fa:eb:5a:ad:ba:4a:5f:a2:   2c:5e:b9:84:ca:a0:33:1f:75:b3:c6:fa:73:08:56:    51:db:e6:34:5f:1f:f7:e8:2d:aa:da:bb:86:3e:f0:    33:6b:f8:e4:d6:ef:76:b2:f3:88:b4:9f:c0:b0:74:   8e:2e:2c:00:07:17:53:2c:91:d4:8a:7c:b1:67:d5:    07:26:14:18:c5:b2:95:cd:aa:7c:90:a3:75:b5:2c:   5b:f2:a0:bc:b6:bf:ba:ed:40:68:77:a0:59:6e:83:   4a:7c:12:0b:ae:ad:6e:07:9a:07:1f:b2:86:f2:a3:   a2:f3:e0:83:4c:e5:6a:8d:27:ba:a2:96:d3:01:46:    49:2b:89:eb:e1:3b:f2:23:2f:c5:08:73:83:02:f7:    81prime1:    00:f7:d6:98:41:75:64:e2:61:42:17:a0:cd:a9:86:   b6:f1:f7:87:c2:60:88:97:5c:7b:eb:29:55:0b:e9:    37:a0:e7:28:1f:54:8b:69:7e:1a:85:96:d0:28:01:   8b:82:2d:ed:19:9f:c1:79:d6:01:2a:2f:fa:62:fe:    43:76:58:d2:47:85:ca:0f:47:e2:a6:5e:cb:2a:f1:    75:b8:72:e4:ec:9c:dd:2f:ce:d1:76:5b:c4:98:1d:    04:de:83:9e:c3:3b:be:4f:97:78:b7:74:a2:49:4e:    32:42:a6:82:14:ec:57:f2:cf:8d:a9:5e:47:a2:cb:    48:d0:c7:54:16:30:e8:31:65prime2:    00:e6:4a:4d:27:53:e6:e9:f0:d6:00:92:cd:36:a3:   c6:ac:32:9c:6f:dd:da:86:6a:58:22:c8:74:1b:a0:   c9:92:52:71:1d:51:e9:77:1f:a9:a0:b9:04:76:e3:    79:32:d0:8a:ee:37:07:6a:88:2e:53:2c:cd:b8:3d:    53:63:df:a6:54:b6:a4:43:82:b3:b2:9b:0b:f6:08:   2a:79:c5:d2:9a:43:3b:0f:50:6a:2f:53:9d:27:d2:   4f:8c:97:a8:dc:23:eb:8a:46:12:a9:22:8e:37:3c:   0d:8e:67:de:90:db:98:a5:32:97:68:46:66:3e:b7:    58:5f:47:79:fa:6a:82:b3:b5exponent1:    00:c0:a1:40:b2:10:06:9b:95:b0:83:20:ee:f9:06:   c6:07:07:b7:b3:32:c8:b7:ac:a0:7c:45:21:df:22:    23:a4:a2:46:23:23:d9:3f:e3:4d:c5:eb:54:5a:e3:   e8:85:04:21:37:3b:5e:6b:ce:14:15:b0:38:d2:dc:    81:9e:e8:a6:78:04:da:ea:49:9b:36:68:93:4d:0b:    63:ce:3b:2f:07:61:5c:e1:9d:c4:5c:54:33:57:6f:   a6:ab:34:6e:1f:9c:bd:ec:aa:f4:9e:d2:be:98:6f:    78:cd:29:12:0e:25:2c:ae:82:f7:be:5e:93:1b:4b:    19:8b:7c:82:34:c5:4a:93:a9exponent2:    00:87:aa:1d:e9:9d:33:db:7d:55:94:e0:e6:a3:d9:   b7:a0:99:f0:2e:b6:b3:95:9b:f0:70:0d:46:d9:3f:   cf:7f:b3:b1:8f:64:41:f5:3b:61:e2:9d:1c:54:2d:   8d:a8:b1:d2:26:a3:a4:6a:cd:ee:fc:70:d8:80:41:    20:6f:25:c2:07:05:d1:9f:33:d0:48:d7:ae:24:32:   8b:53:51:86:cf:f9:eb:41:0a:4e:83:b2:ee:52:17:    43:65:bf:b2:6a:7d:7e:b4:e6:b2:f7:90:b3:d7:36:    39:86:3b:0a:92:ab:cb:31:06:ac:cb:71:2d:aa:a4:   b8:1a:e9:30:a2:a5:3c:7a:41coefficient:    73:ab:f8:8b:e9:ff:a1:d4:cc:87:ac:f7:ec:ae:02:   c3:a2:06:f6:a7:03:3d:95:72:d5:d5:d8:fe:67:99:    94:d8:41:67:19:5d:ed:3f:e3:a5:25:10:b4:55:9b:    15:cb:85:ec:9a:35:1b:05:51:dc:d8:05:01:f3:10:   2a:ce:9b:2e:ae:34:8f:60:f9:3c:6d:8d:0b:a5:10:    85:f7:97:08:8b:3e:b6:f7:a7:14:21:d9:f7:f7:97:   c7:f4:ea:fb:bf:fe:41:a1:72:bd:b7:01:b7:e3:48:   ff:11:3c:64:2d:48:7b:d1:96:7b:56:6d:09:e2:8f:    30:35:96:63:55:06:fc:96    #公钥明细Public-Key: (2048 bit)Modulus:    00:de:f2:bb:84:71:1b:95:7a:88:c3:83:a5:01:dc:    98:06:84:a6:e9:36:16:f3:42:87:e9:67:a7:3d:1d:   b8:27:c1:5e:86:9c:41:c9:06:3a:9a:93:13:47:f5:    cc:e0:14:c0:7e:57:e8:ba:f7:4d:67:d3:8f:02:6d:   c8:6a:b1:da:05:b7:35:69:7c:33:9f:39:fd:df:23:   e9:fe:74:1d:05:d6:6a:f5:10:c0:24:0d:5f:e4:44:    ab:09:8f:d8:25:68:81:5b:cf:02:df:71:2d:2c:5d:   b1:88:e8:f5:97:ed:36:1d:ea:5d:16:8d:05:bc:ed:    01:13:5f:72:ad:2d:a6:70:12:c7:f0:b4:d4:60:05:   be:ed:d5:33:8e:89:d2:d6:14:ca:26:8f:a2:d6:bf:    99:c2:ae:83:8e:9e:e6:c4:1e:a1:16:ab:11:48:85:    55:ca:91:5d:ea:0b:36:a3:81:8b:50:94:51:f4:24:   0b:62:87:1e:48:51:02:b1:17:9f:db:98:e1:28:5c:    51:fc:76:8c:64:93:c7:90:ca:3d:5b:c0:8d:57:bb:    30:2d:ab:43:70:e6:ef:f0:02:42:ee:f1:e6:8d:85:    50:0d:2c:5b:40:cc:6d:2b:ef:1f:51:81:8c:c1:2e:    13:2c:79:ed:fc:82:f4:b5:bc:90:5a:eb:e1:d5:fe:   8b:69Exponent: 65537 (0x10001)

代码

////////////////////////////////RSAfunc RSA() { RSAEncDec() RSASignVerify(crypto.SHA256)}func RSAEncDec() { origData := []byte("RSA待加密数据") // 待加密的数据,不能超过指定长度 fmt.Println("原文:", string(origData)) //生成私钥 privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { panic(err) } ShowRSAKeys(privateKey) //生成公钥 publicKey := privateKey.PublicKey //根据公钥加密 encryptedBytes, err := rsa.EncryptOAEP( sha256.New(), rand.Reader, &publicKey, origData, //需要加密的字符串 nil) if err != nil { panic(err) } fmt.Println("密文(bytes): ", encryptedBytes) fmt.Println("密文(hex):", hex.EncodeToString(encryptedBytes)) fmt.Println("密文(base64):", base64.StdEncoding.EncodeToString(encryptedBytes)) //根据私钥解密 decryptedBytes, err := privateKey.Decrypt(nil, encryptedBytes, &rsa.OAEPOptions{Hash: crypto.SHA256}) if err != nil { panic(err) } fmt.Println("decrypted message: ", string(decryptedBytes)) fmt.Println("nn")}//PKCS1格式的keyfunc ShowRSAKeys(rsaPrivateKey *rsa.PrivateKey) { privateKey := string(pem.EncodeToMemory(&pem.Block{ Type:  "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(rsaPrivateKey), })) derPkix, err := x509.MarshalPKIXPublicKey(&rsaPrivateKey.PublicKey) if err != nil { return } publicKey := string(pem.EncodeToMemory(&pem.Block{ Type:  "PUBLIC KEY", Bytes: derPkix, })) fmt.Printf("公钥:%vn私钥:%vn", publicKey, privateKey)}//签名和验签func RSASignVerify(algorithmSign crypto.Hash) { origData := []byte("RSA待签名数据") // 待签名的数据,长度无影响 fmt.Println("原文:", string(origData)) //生成私钥 privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { panic(err) } ShowRSAKeys(privateKey) //生成公钥 publicKey := privateKey.PublicKey //签名 hash := algorithmSign.New() hash.Write(origData) sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey, algorithmSign, hash.Sum(nil)) if err != nil { panic(err) } fmt.Println("签名(bytes): ", sign) fmt.Println("签名(hex):", hex.EncodeToString(sign)) //验签 err = rsa.VerifyPKCS1v15(&publicKey, algorithmSign, hash.Sum(nil), sign) if err == nil { fmt.Println("验签成功") } else { fmt.Println("验签失败") }}func main() { RSA()}

结果:

原文:RSA待加密数据公钥:-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuXBB99idiOOKvY3vdNnzgF0XWOrQj9hKb0lqU9phdGC5ngi7gxQpLgzewFL8/B5sXTEIBBsGsg+szwsjAykvPMjgJs7e6hpnNqCiaX7e936DakCZc7Cgkjv7Qc7Flvy2j+A2OyDntVvu/RwAgRNQMNBJ/QR9ErHmhjFJwain+mN42U0ng4WvObonAJMJ70LASxpdpifW2LnHQijn+HHEJ0ZNDLzBrObcoLw+xjMpSg4GazPhgi6bPpBlIEXOSXkNeQ/k8uGyx9XNor4Vqiql24sSzZnoar1hfpTG7SIAkSuqh8wj7dO/zXkbZ/RfA/EVfzS4XKNfFICnP46XuP6WXQIDAQAB-----END PUBLIC KEY-----私钥:-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAuXBB99idiOOKvY3vdNnzgF0XWOrQj9hKb0lqU9phdGC5ngi7gxQpLgzewFL8/B5sXTEIBBsGsg+szwsjAykvPMjgJs7e6hpnNqCiaX7e936DakCZc7Cgkjv7Qc7Flvy2j+A2OyDntVvu/RwAgRNQMNBJ/QR9ErHmhjFJwain+mN42U0ng4WvObonAJMJ70LASxpdpifW2LnHQijn+HHEJ0ZNDLzBrObcoLw+xjMpSg4GazPhgi6bPpBlIEXOSXkNeQ/k8uGyx9XNor4Vqiql24sSzZnoar1hfpTG7SIAkSuqh8wj7dO/zXkbZ/RfA/EVfzS4XKNfFICnP46XuP6WXQIDAQABAoIBAAPZIIVUKXC9yBNG7sEuBK+VPvbJaKqTgnfsvhgfYAZaO3/cDogZ0wDxo226SyWwO+9zJQdwyCLJ0Hw7bu6R3DkWshAcGuQgyCOKEdS+nUHljjSWQpj0AWEHfZ9P+ym29NLnhDiV5jkNP1hhTGFhVTiuGdr2TOImbvI5853hMhswDDWpgpy66/z40Lma4w4Uk5kCBi5aYs0KCPZgiBQQVIYHXvB0ys6ev0PJgkXOK51H8yqqFORDsQyMQJFqMzQ3N0qKYTIAcdtzxnihLXEZOLBaREXbfCXKWj/ZRQocSPcZEHVlct0hbwxka3/2nCHg12cfn9Wbsq9pj0Dehf3HtAECgYEA4VaEBrIyCnCnH4PxwScTDhBAKolzfQkptsr737Xkpf9xOlbGbJSVmDvuH3ARXbbLVGwtBT9yD5wn01ZrAUgsnCDzKQxLAMbejSaCl7vOXf3ovVNgJiU+SLiw44mfnpcvXYa9OKB3GLY8si2gS4If0PNIvuQuj4+uXmbEbdW6iG0CgYEA0qvfqi8n1n/jRkc+hldQgn8QkGfkUmO8HG9dguCXjGTXJlHfIUCvB65yoPivFLa7FORwWxDuvsoRxW15jg5lYfRo1K0OcIRsWUGRsLPh98H4zey34CYnv4L4DOrKFguskpCC0rj5+9RTBQO4MwnqoGl4N7uOWvr8s06qwSv7b7ECgYAdcGIbRdiHyKPs2B4Tb/lrUvAvHnn6EeJjQS2a0namwTKXvpJ5yQeqNdosPUXnimQSCXfwQZOzOmFxmM6uAjHhy+Q4rqR124Vjx240SJLzcKKhaW0cTq1ObuKdN3OlEndbrqi15zDoB5byaEeS1dM2RzJvzfvPQaQ0LRTojI2sGQKBgQCw6YqTBLSEqbK24r8723kNjRzg143iLkTa8B5r+KTrTgdq85fX+dTCM5mpWgzU7TqfqdI8dzS2XUSdMXjBdY9nufKKnqUgkePW9HwfEoAxKeABNceX4RLB/X7GgiigaL9L+TUTNikfdEcfT+dQXQR+HvPIgaVi+6BYBzjXrVKhkQKBgBvothb8QrSe7GLpMNTr5Y6Y5yJoqezDByeqtNhnjHrmzftGnHI36LF1C7RoxAqjizN9Z/IZhRdkxA59HALjkp7vieoRmlO+VLiW09nX+tLmk7LMeUEWXx7u3Wkp+NfAZywpwWMKzM3aSMtMfvcvVuulZGYFzG33QIP9T9GuX1P7-----END RSA PRIVATE KEY-----密文(bytes): [69 137 219 156 198 176 241 87 252 65 36 93 225 66 98 196 211 200 35 209 28 71 199 70 2 219 241 165 226 149 31 150 121 91 143 42 26 188 203 10 3 143 201 66 120 26 134 138 224 153 60 34 180 189 79 89 249 107 61 209 3 175 145 151 112 189 254 166 107 177 2 28 121 241 16 99 183 88 192 198 161 142 144 18 116 219 158 146 205 10 15 209 58 75 62 197 103 99 130 129 51 135 69 123 44 237 72 46 55 79 51 130 137 160 109 251 82 3 104 86 36 207 120 80 195 47 79 127 115 242 118 234 234 13 213 128 147 226 74 91 86 196 209 212 85 32 171 94 119 165 206 65 225 222 82 73 11 204 108 167 235 2 154 64 208 45 58 100 195 86 243 53 5 49 142 122 52 34 245 177 15 117 162 94 245 154 205 198 160 16 215 191 201 159 6 168 252 52 225 24 19 166 116 88 187 118 106 34 143 243 35 205 212 130 111 215 230 231 187 200 126 144 78 246 85 7 236 2 74 51 4 164 229 202 47 183 220 84 30 198 153 79 189 184 253 72 155 241 136 39 155 88 60 0 85 178]密文(hex):4589db9cc6b0f157fc41245de14262c4d3c823d11c47c74602dbf1a5e2951f96795b8f2a1abccb0a038fc942781a868ae0993c22b4bd4f59f96b3dd103af919770bdfea66bb1021c79f11063b758c0c6a18e901274db9e92cd0a0fd13a4b3ec5676382813387457b2ced482e374f338289a06dfb5203685624cf7850c32f4f7f73f276eaea0dd58093e24a5b56c4d1d45520ab5e77a5ce41e1de52490bcc6ca7eb029a40d02d3a64c356f33505318e7a3422f5b10f75a25ef59acdc6a010d7bfc99f06a8fc34e11813a67458bb766a228ff323cdd4826fd7e6e7bbc87e904ef65507ec024a3304a4e5ca2fb7dc541ec6994fbdb8fd489bf188279b583c0055b2密文(base64):RYnbnMaw8Vf8QSRd4UJixNPII9EcR8dGAtvxpeKV***ZVB+wCSjMEpOXKL7fcVB7GmU+9uP1Im/GIJ5tYPABVsg==decrypted message: RSA待加密数据原文:RSA待签名数据公钥:-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnFXHUNFP7gWmRNyNdXhGcaTrNim4GFKKPBOWLLGN6jURBODRjosJL2B/+6kLPDXCO9tPLPm2suKCVdmlaxgEPoN0g+YA/pmUPBf0B+CJU8fWRZHrpA4aQ9gsCGnfj5bX8U5WCk03YFgkXHbGer1fJkUxK+IksgqOf1Lvr5HPI4oHKjVRA6aOr1qJO82oaQSYSBEmHnQ3Ico7WX2TEQvnt0lrJbt8GDFtcK94Sp+oLr5j/OZy4VFmw+4zNCy2+XpsC5fGcUGEKeLeB3Hm3zkhts6T4imAyCr679dIcNFGgHKHm8uH7c+gNTPfOOjVmOrYgIQRn8j9npR2x0oPnMpvlQIDAQAB-----END PUBLIC KEY-----私钥:-----BEGIN RSA PRIVATE KEY-----MIIEpAIBAAKCAQEAnFXHUNFP7gWmRNyNdXhGcaTrNim4GFKKPBOWLLGN6jURBODRjosJL2B/+6kLPDXCO9tPLPm2suKCVdmlaxgEPoN0g+YA/pmUPBf0B+CJU8fWRZHrpA4aQ9gsCGnfj5bX8U5WCk03YFgkXHbGer1fJkUxK+IksgqOf1Lvr5HPI4oHKjVRA6aOr1qJO82oaQSYSBEmHnQ3Ico7WX2TEQvnt0lrJbt8GDFtcK94Sp+oLr5j/OZy4VFmw+4zNCy2+XpsC5fGcUGEKeLeB3Hm3zkhts6T4imAyCr679dIcNFGgHKHm8uH7c+gNTPfOOjVmOrYgIQRn8j9npR2x0oPnMpvlQIDAQABAoIBACgrwnN51VgMC5VWNuMgbLl27xmTzsIxM2QMhGInnZe42w6t1isSfuG1oi1AWqq2BZrr14RvBgshOOxmaKMEINMPZDkgONEzFWv7m7EKeT8V8nEd9bbKCOW1/lqLGe8Di6ltv54WCUy***Fnp12zG5iDct24hPGzvmXBZXBGj5C/8DESU/y1HRUxAO6KTPX8lPdweyQKNdL2p/UMbdXEeMro/L8FNh+OkAltSRdAuTj5VDdrgQa022Qd/h9JxpagbZD1A6tyupQAAsUTZcBJbTeij9jvyOPS22SelQVEgY5B8QiB81GsWps37WECgYEAwLt2jNRBHsMyIfdhJAsdatRalkdjuDRydW3+5PRDuwPnf7TxxZCneNEya0qXGV2Dk5MfiTB1WuD6tzjaJOpaiK6slQhrBq/JB54j8cdDpvN9a5Sjum0zJsQPgL/4NQUgGf2U2shbtxzSG2t3MgQhjPOqoF5bOl5/cWLygLxC5gcCgYEAz6efnPhRryUFs9ng5rsQPCRb9gHhapoeqKAToawyAiRvfMQxSMV61gdjXJRV+3wnbvdNUc2In6YdHsCC26LtgEyYPoSmIUf/7T3MZ8MM6s/YTeA0l/+3qtCX5MazBXxxww64WylZCpucO+dKfaUsoTr6qUc2j2eu7YATRFVc9oMCgYEAvj3MzUIObYEbkS+QcXWPOg4WxNP++Kq8eHF08yaxXH6EGijPpcYdqUJF1GYyM9V8tUS6Ej8E+AmvMQArQ9kYOGbC7/D5RAZsFtrgfB3HB5q9KF32J2T24sMQ0nOrWxqOD1mhfzvaXCtUscAoTfSJ8Ynr2JSK1FjGz3NuD+jE2C0CgYEAhqiZzg4N0nk8qHO674URMx8U74QqrJmDFjCwamAjEdaU4aDMoPdG//JMkeWzmGDbpY8Dee/CEF2FdsK6WTnfsBp7g9c7cEujgDJaElOfVcow59dj48m1TjT0uyvLPdyEXUx3as52anWcrBAB81agiXGYyRtgG0DOZD9wvxhoL4cCgYA6WrasukE5w7wzoRRPIVSGwnSeiG4A8uDaGKa0eNWSoHbggKUTutQ2wnB1O89n4AyDN9tIXKxT0XH3a96AA0RUsW9apbQeuyxGAf2R+varlaLsm99xP2x67YfRXcLByG+RIQDRx//HR64k+BptmZ4MyLp7hyAi4XtXLEO4B9Rpmg==-----END RSA PRIVATE KEY-----签名(bytes): [153 8 165 215 86 112 125 54 204 34 44 38 124 183 171 194 144 68 37 38 210 196 74 40 85 71 25 34 3 93 46 254 247 191 232 198 228 12 115 87 237 246 46 226 229 73 222 230 38 57 54 170 219 254 87 204 235 9 249 235 190 30 77 185 20 55 100 97 249 103 120 65 231 138 214 148 175 134 157 0 205 64 36 16 19 238 33 81 63 36 155 154 119 140 43 248 192 219 98 133 241 91 88 236 181 76 78 238 236 164 183 196 170 178 39 91 79 147 198 45 85 206 101 71 159 136 182 225 141 88 126 60 59 53 251 170 5 30 153 239 89 180 148 216 237 218 163 205 150 151 115 73 13 10 147 78 180 251 29 80 185 17 194 61 112 191 136 240 142 182 60 228 191 225 123 162 3 217 224 59 208 95 114 166 27 173 171 139 178 248 82 72 124 209 230 78 245 86 122 213 171 158 113 91 11 158 128 196 152 134 64 21 120 77 148 95 249 6 70 51 24 233 222 160 180 218 27 132 162 237 110 126 188 125 110 130 249 177 108 159 141 121 19 66 78 72 208 38 124 228 141 124 77 79 149 221]签名(hex):9908a5d756707d36cc222c267cb7abc290442526d2c44a2855471922035d2efef7bfe8c6e40c7357edf62ee2e549dee6263936aadbfe57cceb09f9ebbe1e4db914376461f9677841e78ad694af869d00cd40241013ee21513f249b9a778c2bf8c0db6285f15b58ecb54c4eeeeca4b7c4aab2275b4f93c62d55ce65479f88b6e18d587e3c3b35fbaa051e99ef59b494d8eddaa3cd969773490d0a934eb4fb1d50b911c23d70bf88f08eb63ce4bfe17ba203d9e03bd05f72a61badab8bb2f852487cd1e64ef5567ad5ab9e715b0b9e80c498864015784d945ff906463318e9dea0b4da1b84a2ed6e7ebc7d6e82f9b16c9f8d7913424e48d0267ce48d7c4d4f95dd验签成功

摘要算法-SHA256

说明

摘要算法比对称算法和非对称算法要容易理解。

对于任意长度的消息,SHA256都会产生一个256bit长的哈希值,称作消息摘要。这个摘要相当于是个长度为32个字节的数组,通常用一个长度为64的十六进制字符串来表示。

摘要计算的速度比较快:

以一个60M的文件为测试样本,经过1000次的测试平均值,三种算法的表现为:

MD5算法运行1000次的平均时间为:226ms

SHA1算法运行1000次的平均时间为:308ms

SHA256算法运行1000次的平均时间为:473ms

代码

func SHA256() { src := "sha256待处理数据" fmt.Println("原文:", string(src)) m := sha256.New() m.Write([]byte(src)) res := hex.EncodeToString(m.Sum(nil)) fmt.Println("sha256摘要数据:", res) //长度256bit,64字节 fmt.Println("nn")}func main() { SHA256()}

结果:

原文:sha256待处理数据

sha256摘要数据:703d4c3b6d0a73831112d78b0369511483f0de671839c79b119a6587394b7237

最后

对于上面的算法只进行了简单介绍,具体的实现逻辑大家可以找资料继续研究。

世界果然是数学的!

计算机追到根上,都是数学!

资料

  1. golang rc4加密算法的使用
  2. 什么是对称加密(对称加密简介)
  3. Golang里的AES加密、解密
  4. 高级加密标准(Advanced Encryption Standard,AES)
  5. 密码学基础:AES加密算法
  6. AES五种加密模式(CBC、ECB、CTR、OCF、CFB)
  7. AES加密模式总结
  8. RSA加密的限制
  9. golang实现RSA加密解密算法
  10. RSA算法多种生成公私钥的方式
  11. RSA密钥证书的生成
  12. (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  13. 关于RSA加密/解密中OAEP填充模式和PKCS1-v1_5填充模式时对于原文数据的要求
  14. golang语言rsa加解密及签名验签
  15. RSA签名和验签
  16. RSA加密、解密、签名、验签(验证签名)&RSA算法原理
  17. SHA256简介
  18. 加密算法比较:SHA1,SHA256(SHA2),MD5
  19. 【Golang】golang实现sha256加密函数

最后

我的个人博客为:https://shidawuhen.github.io/

往期文章回顾:

  1. 设计模式
  2. 招聘
  3. 思考
  4. 存储
  5. 算法系列
  6. 读书笔记
  7. 小工具
  8. 架构
  9. 网络
  10. Go语言

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:dandanxi6@qq.com

(0)
上一篇 2023年 4月 6日 下午1:03
下一篇 2023年 4月 6日 下午1:09

相关推荐

  • 世界上著名的蛋糕

    1 德国【黑森林蛋糕】 德国最为出名的就是味道浓郁的黑森林蛋糕,融合了樱桃的酸、奶油的甜、巧克力的苦、樱桃酒的醇香。完美的黑森林蛋糕经得起各种口味的挑剔。 以饱满的酒渍樱桃与比例惊…

    2023年 3月 24日
  • 没吃完的腊肉如何保存,腊肉怎么放不变质

    没吃完的腊肉,牢记别直接放冰箱,教你一招,放一年不变干不变味 在南方,春节必备的年货就是腊味,制作腊制品是古人保存肉类的一种方式,没想到现在成了一种风味美食,家家户户在年前都要准备…

    2023年 7月 16日
  • 顺德美食一日游攻略最佳路线

    这几天广东的天气实在是太好了,阳光明媚,万里无云,正是出游的好时节。 咱们说走就走,周末去顺德觅食!我是从广州这边打车过去的,避开节假日去就是好,路上一路畅通,一个午休的时间都不用…

    2023年 2月 10日
  • 杭州确定成国家中心城市吗(杭州有可能成为国家中心城市吗)

    **中央选定杭州建长三角中心城市,真实的杭州有多硬核,为何选它?** 近日,中央政府宣布选定杭州为长三角地区的中心城市,引发了广泛关注和热议。杭州,这座历史悠久、文化灿烂的城市,以…

    2023年 8月 21日
  • 青蛙主要是吃什么为生

    在农村流传着这么一句谚语:大蟆吃小蟆,小蟆吃蚂蚱。蟆,指蛤蟆,是农民朋友对蛙类的统称。虽然该谚语的原意是比喻以大欺小,但是从这句谚语中,我们也不难看出,青蛙喜肉食、昆虫之类的食物。…

    2023年 6月 30日
  • 康熙的儿子们的名字都是什么

    康熙皇帝35个儿子,比较出名的只有这几位,大阿哥,二阿哥,四阿哥,八阿哥,九阿哥,十阿哥,十三阿哥,十四阿哥,这都是九子夺嫡的关键人物。 康熙最疼爱哪位阿哥? 这是众所周知,太子胤…

    2023年 1月 20日
  • 干蒜鸭脯肉 低成本高毛利的菜品 特别让人喜欢

    干蒜鸭脯肉 原料 带皮的大蒜瓣300克,鸭脯肉2块(约200克)。 调料 A料(排骨酱、海鲜酱各5克,蚝油3克,鸡蛋清20克,淀粉10克),色拉油1千克(约耗60克),青、红椒段各…

    2022年 12月 18日
  • 集成墙板上的胶水怎么去掉(集成墙板胶印用什么擦干净)

    手上的玻璃胶去除方法有:   1、双手互搓:如果粘到手上的玻璃胶还没有固化,用清水洗刷一下就容易去除,如果玻璃胶固化,也不用担心,玻璃胶固化后是粘不牢手的,反复地将自己的双手互相搓…

    生活知识 2024年 1月 17日
  • 烟台葡萄酒广告语征集揭晓

    胶东在线消息 近日,从烟台市商务局获悉,为进一步凝练烟台葡萄酒特色,提升烟台葡萄酒的影响力和知名度,决定在全国范围内征集烟台葡萄酒广告宣传语。 本次征集时间为2021年9月2日至9…

    生活知识 2023年 1月 19日
  • 预防心脑血管病的食物有哪些(糖友防止心脑血管疾病吃什么好)

    日前,美国哈佛大学一项研究颇有新意,研究人员从食物、营养素与人体内炎症相关性这样的角度,来探索吃不同的食物影响体内炎症状况,从而与心血管病、冠心病、中风风险的影响相关性进行研究。研…

    生活知识 2022年 12月 26日