常用密码算法介绍

密码算法是信息安全领域的基础,它们用于保护数据免受未授权访问。以下是一些常用的密码算法及其简介:
### 对称加密算法
1. "DES(数据加密标准)":一种使用56位密钥的对称加密算法,由IBM开发,后被美国国家标准与技术研究院采纳为标准。 2. "AES(高级加密标准)":一种更安全的对称加密算法,使用128、192或256位密钥,被广泛用于现代加密应用。 3. "3DES(三重数据加密算法)":DES的变种,使用三个DES密钥,提供比DES更强的安全性。
### 非对称加密算法
1. "RSA":基于大数分解的困难性,使用两个密钥(公钥和私钥),广泛应用于数字签名和加密。 2. "ECC(椭圆曲线加密)":基于椭圆曲线数学,提供比RSA更短的密钥长度,但同样安全。 3. "Diffie-Hellman":一种密钥交换协议,允许双方在不安全的通道上安全地交换密钥。
### 哈希算法
1. "MD5":一种广泛使用的哈希函数,但已不再安全,因为存在碰撞攻击。 2. "SHA-1":MD5的改进版本,但同样存在安全风险。 3. "SHA-256":更安全的哈希算法,广泛用于加密和数字签名

相关内容:

算法种类

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

对称算法

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

子算法:

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

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

非对称算法

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

  • 公钥加密,私钥解密
  • 私钥加签,公钥验签
常见算法:RSA、DH、DSA、ECDSA、ECC、SM2

摘要算法

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

常见算法:MD5、SHA1、SM3

实战

对称算法-RC4

说明

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

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

代码

package main
import (
  "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("%x
", 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 

", 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模式。

代码

////////////////////////////////AES
func 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) // 加密模式,key是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) // 加密模式
  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)
  return origData
}
// =================== 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 = 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, plain)
  }
  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, encrypted)
  }
  trim := 0
  if len(decrypted) > 0 {
    trim = len(decrypted) - int(decrypted)
  }
  return decrypted
}
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 ^= key
    }
  }
  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-----
MIIEpAIBAAKCAQEA3vK7hHEblXqIw4OlAdyYBoSm6TYW80KH6WenPR24J8FehpxB
yQY6mpMTR/XM4BTAflfouvdNZ9OPAm3IarHaBbc1aXwznzn93yPp/nQdBdZq9RDA
JA1f5ESrCY/YJWiBW88C33EtLF2xiOj1l+02HepdFo0FvO0BE19yrS2mcBLH8LTU
YAW+7dUzjonS1hTKJo+i1r+Zwq6Djp7mxB6hFqsRSIVVypFd6gs2o4GLUJRR9CQL
YoceSFECsRef25jhKFxR/HaMZJPHkMo9W8CNV7swLatDcObv8AJC7vHmjYVQDSxb
QMxtK+8fUYGMwS4TLHnt/IL0tbyQWuvh1f6LaQIDAQABAoIBAEQCl+FW/6shrga2
aeefe2DBpokNzwJ2ES/KRuIF5t95xXQaxpakJ8xvgTo6aT0SF4ZzGrOuLRa3GrEK
/FBP4MpNkSWUlcrEzgT7162fjhrxxb7sVTCqQ85GhEZucuk2b/+prp6qz7Tw/+9b
4U9vNUr661qtukpfoixeuYTKoDMfdbPG+nMIVlHb5jRfH/foLarau4Y+8DNr+OTW
73ay84i0n8CwdI4uLAAHF1MskdSKfLFn1QcmFBjFspXNqnyQo3W1LFvyoLy2v7rt
QGh3oFlug0p8EguurW4Hmgcfsobyo6Lz4INM5WqNJ7qiltMBRkkrievhO/IjL8UI
c4MC94ECgYEA99aYQXVk4mFCF6DNqYa28feHwmCIl1x76ylVC+k3oOcoH1SLaX4a
hZbQKAGLgi3tGZ/BedYBKi/6Yv5DdljSR4XKD0fipl7LKvF1uHLk7JzdL87RdlvE
mB0E3oOewzu+T5d4t3SiSU4yQqaCFOxX8s+NqV5HostI0MdUFjDoMWUCgYEA5kpN
J1Pm6fDWAJLNNqPGrDKcb93ahmpYIsh0G6DJklJxHVHpdx+poLkEduN5MtCK7jcH
aoguUyzNuD1TY9+mVLakQ4KzspsL9ggqecXSmkM7D1BqL1OdJ9JPjJeo3CPrikYS
qSKONzwNjmfekNuYpTKXaEZmPrdYX0d5+mqCs7UCgYEAwKFAshAGm5WwgyDu+QbG
Bwe3szLIt6ygfEUh3yIjpKJGIyPZP+NNxetUWuPohQQhNztea84UFbA40tyBnuim
eATa6kmbNmiTTQtjzjsvB2Fc4Z3EXFQzV2+mqzRuH5y97Kr0ntK+mG94zSkSDiUs
roL3vl6TG0sZi3yCNMVKk6kCgYEAh6od6Z0z231VlODmo9m3oJnwLrazlZvwcA1G
2T/Pf7Oxj2RB9Tth4p0cVC2NqLHSJqOkas3u/HDYgEEgbyXCBwXRnzPQSNeuJDKL
U1GGz/nrQQpOg7LuUhdDZb+yan1+tOay95Cz1zY5hjsKkqvLMQasy3EtqqS4Gukw
oqU8ekECgYBzq/iL6f+h1MyHrPfsrgLDogb2pwM9lXLV1dj+Z5mU2EFnGV3tP+Ol
JRC0VZsVy4XsmjUbBVHc2AUB8xAqzpsurjSPYPk8bY0LpRCF95cIiz6296cUIdn3
95fH9Or7v/5BoXK9twG340j/ETxkLUh70ZZ7Vm0J4o8wNZZjVQb8lg==
-----END RSA PRIVATE KEY-----
生成RSA公钥

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

openssl rsa -in rsa_private.key -pubout -out rsa_public.key
#查看rsa_public.key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3vK7hHEblXqIw4OlAdyY
BoSm6TYW80KH6WenPR24J8FehpxByQY6mpMTR/XM4BTAflfouvdNZ9OPAm3IarHa
Bbc1aXwznzn93yPp/nQdBdZq9RDAJA1f5ESrCY/YJWiBW88C33EtLF2xiOj1l+02
HepdFo0FvO0BE19yrS2mcBLH8LTUYAW+7dUzjonS1hTKJo+i1r+Zwq6Djp7mxB6h
FqsRSIVVypFd6gs2o4GLUJRR9CQLYoceSFECsRef25jhKFxR/HaMZJPHkMo9W8CN
V7swLatDcObv8AJC7vHmjYVQDSxbQMxtK+8fUYGMwS4TLHnt/IL0tbyQWuvh1f6L
aQIDAQAB
-----END PUBLIC KEY-----
查看公/私钥明细

openssl rsa -in rsa_private.key -noout -text
openssl 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:69
publicExponent: 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:
    81
prime1:
    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:65
prime2:
    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:b5
exponent1:
    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:a9
exponent2:
    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:41
coefficient:
    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:69
Exponent: 65537 (0x10001)

代码

////////////////////////////////RSA
func 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("

")
}
//PKCS1格式的key
func 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("公钥:%v
私钥:%v
", 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-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuXBB99idiOOKvY3vdNnz
gF0XWOrQj9hKb0lqU9phdGC5ngi7gxQpLgzewFL8/B5sXTEIBBsGsg+szwsjAykv
PMjgJs7e6hpnNqCiaX7e936DakCZc7Cgkjv7Qc7Flvy2j+A2OyDntVvu/RwAgRNQ
MNBJ/QR9ErHmhjFJwain+mN42U0ng4WvObonAJMJ70LASxpdpifW2LnHQijn+HHE
J0ZNDLzBrObcoLw+xjMpSg4GazPhgi6bPpBlIEXOSXkNeQ/k8uGyx9XNor4Vqiql
24sSzZnoar1hfpTG7SIAkSuqh8wj7dO/zXkbZ/RfA/EVfzS4XKNfFICnP46XuP6W
XQIDAQAB
-----END PUBLIC KEY-----
私钥:-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuXBB99idiOOKvY3vdNnzgF0XWOrQj9hKb0lqU9phdGC5ngi7
gxQpLgzewFL8/B5sXTEIBBsGsg+szwsjAykvPMjgJs7e6hpnNqCiaX7e936DakCZ
c7Cgkjv7Qc7Flvy2j+A2OyDntVvu/RwAgRNQMNBJ/QR9ErHmhjFJwain+mN42U0n
g4WvObonAJMJ70LASxpdpifW2LnHQijn+HHEJ0ZNDLzBrObcoLw+xjMpSg4GazPh
gi6bPpBlIEXOSXkNeQ/k8uGyx9XNor4Vqiql24sSzZnoar1hfpTG7SIAkSuqh8wj
7dO/zXkbZ/RfA/EVfzS4XKNfFICnP46XuP6WXQIDAQABAoIBAAPZIIVUKXC9yBNG
7sEuBK+VPvbJaKqTgnfsvhgfYAZaO3/cDogZ0wDxo226SyWwO+9zJQdwyCLJ0Hw7
bu6R3DkWshAcGuQgyCOKEdS+nUHljjSWQpj0AWEHfZ9P+ym29NLnhDiV5jkNP1hh
TGFhVTiuGdr2TOImbvI5853hMhswDDWpgpy66/z40Lma4w4Uk5kCBi5aYs0KCPZg
iBQQVIYHXvB0ys6ev0PJgkXOK51H8yqqFORDsQyMQJFqMzQ3N0qKYTIAcdtzxnih
LXEZOLBaREXbfCXKWj/ZRQocSPcZEHVlct0hbwxka3/2nCHg12cfn9Wbsq9pj0De
hf3HtAECgYEA4VaEBrIyCnCnH4PxwScTDhBAKolzfQkptsr737Xkpf9xOlbGbJSV
mDvuH3ARXbbLVGwtBT9yD5wn01ZrAUgsnCDzKQxLAMbejSaCl7vOXf3ovVNgJiU+
SLiw44mfnpcvXYa9OKB3GLY8si2gS4If0PNIvuQuj4+uXmbEbdW6iG0CgYEA0qvf
qi8n1n/jRkc+hldQgn8QkGfkUmO8HG9dguCXjGTXJlHfIUCvB65yoPivFLa7FORw
WxDuvsoRxW15jg5lYfRo1K0OcIRsWUGRsLPh98H4zey34CYnv4L4DOrKFguskpCC
0rj5+9RTBQO4MwnqoGl4N7uOWvr8s06qwSv7b7ECgYAdcGIbRdiHyKPs2B4Tb/lr
UvAvHnn6EeJjQS2a0namwTKXvpJ5yQeqNdosPUXnimQSCXfwQZOzOmFxmM6uAjHh
y+Q4rqR124Vjx240SJLzcKKhaW0cTq1ObuKdN3OlEndbrqi15zDoB5byaEeS1dM2
RzJvzfvPQaQ0LRTojI2sGQKBgQCw6YqTBLSEqbK24r8723kNjRzg143iLkTa8B5r
+KTrTgdq85fX+dTCM5mpWgzU7TqfqdI8dzS2XUSdMXjBdY9nufKKnqUgkePW9Hwf
EoAxKeABNceX4RLB/X7GgiigaL9L+TUTNikfdEcfT+dQXQR+HvPIgaVi+6BYBzjX
rVKhkQKBgBvothb8QrSe7GLpMNTr5Y6Y5yJoqezDByeqtNhnjHrmzftGnHI36LF1
C7RoxAqjizN9Z/IZhRdkxA59HALjkp7vieoRmlO+VLiW09nX+tLmk7LMeUEWXx7u
3Wkp+NfAZywpwWMKzM3aSMtMfvcvVuulZGYFzG33QIP9T9GuX1P7
-----END RSA PRIVATE KEY-----
密文(bytes):  
密文(hex):4589db9cc6b0f157fc41245de14262c4d3c823d11c47c74602dbf1a5e2951f96795b8f2a1abccb0a038fc942781a868ae0993c22b4bd4f59f96b3dd103af919770bdfea66bb1021c79f11063b758c0c6a18e901274db9e92cd0a0fd13a4b3ec5676382813387457b2ced482e374f338289a06dfb5203685624cf7850c32f4f7f73f276eaea0dd58093e24a5b56c4d1d45520ab5e77a5ce41e1de52490bcc6ca7eb029a40d02d3a64c356f33505318e7a3422f5b10f75a25ef59acdc6a010d7bfc99f06a8fc34e11813a67458bb766a228ff323cdd4826fd7e6e7bbc87e904ef65507ec024a3304a4e5ca2fb7dc541ec6994fbdb8fd489bf188279b583c0055b2
密文(base64):RYnbnMaw8Vf8QSRd4UJixNPII9EcR8dGAtvxpeKVH5Z5W48qGrzLCgOPyUJ4GoaK4Jk8IrS9T1n5az3RA6+Rl3C9/qZrsQIcefEQY7dYwMahjpASdNueks0KD9E6Sz7FZ2OCgTOHRXss7UguN08zgomgbftSA2hWJM94UMMvT39z8nbq6g3VgJPiSltWxNHUVSCrXnelzkHh3lJJC8xsp+sCmkDQLTpkw1bzNQUxjno0IvWxD3WiXvWazcagENe/yZ8GqPw04RgTpnRYu3ZqIo/zI83Ugm/X5ue7yH6QTvZVB+wCSjMEpOXKL7fcVB7GmU+9uP1Im/GIJ5tYPABVsg==
decrypted message:  RSA待加密数据
原文:RSA待签名数据
公钥:-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnFXHUNFP7gWmRNyNdXhG
caTrNim4GFKKPBOWLLGN6jURBODRjosJL2B/+6kLPDXCO9tPLPm2suKCVdmlaxgE
PoN0g+YA/pmUPBf0B+CJU8fWRZHrpA4aQ9gsCGnfj5bX8U5WCk03YFgkXHbGer1f
JkUxK+IksgqOf1Lvr5HPI4oHKjVRA6aOr1qJO82oaQSYSBEmHnQ3Ico7WX2TEQvn
t0lrJbt8GDFtcK94Sp+oLr5j/OZy4VFmw+4zNCy2+XpsC5fGcUGEKeLeB3Hm3zkh
ts6T4imAyCr679dIcNFGgHKHm8uH7c+gNTPfOOjVmOrYgIQRn8j9npR2x0oPnMpv
lQIDAQAB
-----END PUBLIC KEY-----
私钥:-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAnFXHUNFP7gWmRNyNdXhGcaTrNim4GFKKPBOWLLGN6jURBODR
josJL2B/+6kLPDXCO9tPLPm2suKCVdmlaxgEPoN0g+YA/pmUPBf0B+CJU8fWRZHr
pA4aQ9gsCGnfj5bX8U5WCk03YFgkXHbGer1fJkUxK+IksgqOf1Lvr5HPI4oHKjVR
A6aOr1qJO82oaQSYSBEmHnQ3Ico7WX2TEQvnt0lrJbt8GDFtcK94Sp+oLr5j/OZy
4VFmw+4zNCy2+XpsC5fGcUGEKeLeB3Hm3zkhts6T4imAyCr679dIcNFGgHKHm8uH
7c+gNTPfOOjVmOrYgIQRn8j9npR2x0oPnMpvlQIDAQABAoIBACgrwnN51VgMC5VW
NuMgbLl27xmTzsIxM2QMhGInnZe42w6t1isSfuG1oi1AWqq2BZrr14RvBgshOOxm
aKMEINMPZDkgONEzFWv7m7EKeT8V8nEd9bbKCOW1/lqLGe8Di6ltv54WCUywWWeI
/ac8Ud67mM715Qf6vnLpFL3AccFnp12zG5iDct24hPGzvmXBZXBGj5C/8DESU/y1
HRUxAO6KTPX8lPdweyQKNdL2p/UMbdXEeMro/L8FNh+OkAltSRdAuTj5VDdrgQa0
22Qd/h9JxpagbZD1A6tyupQAAsUTZcBJbTeij9jvyOPS22SelQVEgY5B8QiB81Gs
Wps37WECgYEAwLt2jNRBHsMyIfdhJAsdatRalkdjuDRydW3+5PRDuwPnf7TxxZCn
eNEya0qXGV2Dk5MfiTB1WuD6tzjaJOpaiK6slQhrBq/JB54j8cdDpvN9a5Sjum0z
JsQPgL/4NQUgGf2U2shbtxzSG2t3MgQhjPOqoF5bOl5/cWLygLxC5gcCgYEAz6ef
nPhRryUFs9ng5rsQPCRb9gHhapoeqKAToawyAiRvfMQxSMV61gdjXJRV+3wnbvdN
Uc2In6YdHsCC26LtgEyYPoSmIUf/7T3MZ8MM6s/YTeA0l/+3qtCX5MazBXxxww64
WylZCpucO+dKfaUsoTr6qUc2j2eu7YATRFVc9oMCgYEAvj3MzUIObYEbkS+QcXWP
Og4WxNP++Kq8eHF08yaxXH6EGijPpcYdqUJF1GYyM9V8tUS6Ej8E+AmvMQArQ9kY
OGbC7/D5RAZsFtrgfB3HB5q9KF32J2T24sMQ0nOrWxqOD1mhfzvaXCtUscAoTfSJ
8Ynr2JSK1FjGz3NuD+jE2C0CgYEAhqiZzg4N0nk8qHO674URMx8U74QqrJmDFjCw
amAjEdaU4aDMoPdG//JMkeWzmGDbpY8Dee/CEF2FdsK6WTnfsBp7g9c7cEujgDJa
ElOfVcow59dj48m1TjT0uyvLPdyEXUx3as52anWcrBAB81agiXGYyRtgG0DOZD9w
vxhoL4cCgYA6WrasukE5w7wzoRRPIVSGwnSeiG4A8uDaGKa0eNWSoHbggKUTutQ2
wnB1O89n4AyDN9tIXKxT0XH3a96AA0RUsW9apbQeuyxGAf2R+varlaLsm99xP2x6
7YfRXcLByG+RIQDRx//HR64k+BptmZ4MyLp7hyAi4XtXLEO4B9Rpmg==
-----END RSA PRIVATE KEY-----
签名(bytes):  
签名(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("

")
}
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语言

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章