十七、encoding
包
包 encoding 定义了由其他包共享的接口,这些包在字节级和文本表示之间转换数据。检查这些接口的包包括encoding/gob、encoding/json和encoding/xml。因此,实现一次接口可以使一个类型在多种编码中有用。实现这些接口的标准类型包括 time.Time 和net.IP。接口成对出现,产生和使用编码数据。
类型
BinaryMarshaler
type BinaryMarshaler interface {
MarshalBinary() (data []byte, err error)
}
BinaryMarshaler是由一个对象实现的接口,该对象可以将自己编组为二进制形式。
MarshalBinary 将接收器(receiver )编码为二进制形式并返回结果。
BinaryUnmarshaler
type BinaryUnmarshaler interface {
UnmarshalBinary(data []byte) error
}
BinaryUnmarshaler是一个由对象实现的接口,该对象可以对自身的二进制表示进行解组。
UnmarshalBinary必须能够解码MarshalBinary生成的格式。如果UnmarshalBinary希望在返回后保留数据,则必须复制数据。
TextMarshaler
type TextMarshaler interface {
MarshalText() (text []byte, err error)
}
TextMarshaler是由对象实现的接口,该对象可以将自己编组为文本形式。
MarshalText将接收器编码为utf -8编码的文本并返回结果。
TextUnmarshaler
type TextUnmarshaler interface {
UnmarshalText(text []byte) error
}
TextUnmarshaler是由对象实现的接口,该对象可以对自身的文本表示进行解组。
UnmarshalText必须能够解码MarshalText生成的表单。如果UnmarshalText希望在返回后保留文本,则必须复制文本。
17.1 json
Package json实现了RFC 7159中定义的json的编码和解码。JSON和Go值之间的映射在Marshal和Unmarshal函数的文档中有描述。
有关这个包的介绍,请参阅“JSON和Go”
类型
SyntaxError
当 json.Decode()
在解析 JSON 文档发生语法错误时,指定返回一个 SyntaxError
类型的错误:
type SyntaxError struct {
msg string // description of error
// error occurred after reading Offset bytes, from which line and columnnr can be obtained
Offset int64
}
func (e *SyntaxError) Error() string { return e.msg }
SyntaxError是对JSON语法错误的描述。如果不能解析JSON, Unmarshal将返回SyntaxError。
在调用代码中你可以像这样用类型断言测试错误是不是上面的类型:
if serr, ok := err.(*json.SyntaxError); ok {
line, col := findLine(f, serr.Offset)
return fmt.Errorf("%s:%d:%d: %v", f.Name(), line, col, err)
}
Encoder
type Encoder struct {
// contains filtered or unexported fields
}
Encoder将JSON值写入输出流。
func (enc *Encoder) Encode(v any) error
Encode writes the JSON encoding of v to the stream, followed by a newline character.
有关Go值转换为JSON的详细信息,请参阅Marshal的文档。
func (enc *Encoder) SetEscapeHTML(on bool)
SetEscapeHTML指定有问题的HTML字符是否应该在JSON引用的字符串中转义。
默认行为是将&、<和>转义为\u0026、\u003c和\u003e,以避免在HTML中嵌入JSON时可能出现的某些安全问题。
在转义会影响输出可读性的非html设置中,SetEscapeHTML(false)
会禁用此行为。
func (enc *Encoder) SetIndent(prefix, indent string)
SetIndent 指示编码器按照包级函数 Indent (dst、src、prefix、Indent)缩进的方式格式化每个后续编码的值。调用SetIndent("", "")
将禁用缩进。
Decoder
type Decoder struct {
// contains filtered or unexported fields
}
Decoder 从输入流读取和解码 JSON 字符串。
func (dec *Decoder) Decode(v any) error
Decode从它的输入中读取下一个json编码的值,并将其存储在v所指向的值中。
1、Marshal()
func Marshal(v any) ([]byte, error)
Marshal返回v的JSON编码
2、NewEncoder()
func NewEncoder(w io.Writer) *Encoder
NewEncoder 返回一个向 w 写入的 新 Encoder。
3、NewDecoder()
func NewDecoder(r io.Reader) *Decoder
NewDecoder 返回一个从 r 读取的新 Decoder。
解码器引入了自己的缓冲,可以从的r读取请求的JSON值以外的数据。
4、MarshalIndent()
func MarshalIndent(v any, prefix, indent string) ([]byte, error)
MarshalIndent类似于Marshal,但应用Indent来格式化输出。
输出中的每个JSON元素都将以新的行开始,以前缀开始,根据缩进嵌套,后跟一个或多个缩进副本。
17.2 gob
包gob管理在Encoder (发送器)和Decoder (接收器) gobs流 – 二进制值之间转换
17.3 pem
Package pem实现了源于Privacy Enhanced Mail的pem数据编码。PEM编码目前最常见的用途 是在TLS密钥和证书中。参考RFC 1421。
类型
Block
type Block struct {
Type string // The type, taken from the preamble (i.e. "RSA PRIVATE KEY").
Headers map[string]string // Optional headers.
Bytes []byte // The decoded bytes of the contents. Typically a DER encoded ASN.1 structure.
}
17.3.1 Encode()
// Encode将b的PEM编码写入out
func Encode(out io.Writer, b *Block) error
17.3.2 Decode()
func Decode(data []byte) (p *Block, rest []byte)
Decode将在输入中找到下一个PEM格式的块(证书,私钥等)。它将返回该块和输入的其余部分。如果没有找到PEM数据,p为nil,整个输入将以rest形式返回。
十八、syscall
包
包 syscall 包含到低级操作系统原语的接口。
细节取决于底层系统,默认情况下,godoc将显示当前系统的系统调用文档。如果您希望godoc显示其他系统的系统调用文档,请将$GOOS
和$GOARCH
设置为所需的系统。
syscall 的主要用途是在向系统提供更可移植接口的其他包中,例如“os”、“time”和“net”。
如果可以的话,使用那些软件包而不是这个软件包
有关此包中的函数和数据类型的详细信息,请参阅相应操作系统的手册
这些调用返回err == nil表示成功;否则,err是描述失败的操作系统错误。在大多数系统上,该错误类型为syscal . errno。
Deprecated:此包被锁定。调用者应该使用golang.org/x/sys存储库中的相应包。这也是应该应用新系统或版本所需的更新的地方。
See https://golang.org/s/go1.4-syscall for more information.
十九、strings
包
包 strings 实现了操作UTF-8编码字符串的简单函数。
19.1 Join()
func Join(elems []string, sep string) string
Join 连接其第一个参数的元素以创建单个字符串。分隔符字符串sep被放置在结果字符串的元素之间
19.2 LastIndex()
func LastIndex(s, substr string) int
LastIndex返回s中substr的最后一个实例的索引,如果s中没有substr,则返回-1。
二十、crypto
包
20.1 sha256
sha256包实现FIPS 180-4中定义的SHA224和sha256哈希算法。
Constants
// SHA256和SHA224的块大小(以字节为单位)。
const BlockSize = 64
// SHA256校验和的大小,以字节为单位。
const Size = 32
// SHA224校验和的大小,以字节为单位。
const Size224 = 28
20.1.1 Sum256()
func Sum256(data []byte) [Size]byte
Sum256返回数据的SHA256校验和( checksum )。
20.1.2 Sum224()
func Sum224(data []byte) [Size224]byte
Sum224返回数据的SHA224校验和。
20.2 des
包 des 实现了美国联邦信息处理标准出版物46-3中定义的数据加密标准des (Data Encryption Standard)和三重数据加密算法TDEA (Triple Data Encryption Algorithm)。
DES在密码学上被破解了,不应该用于安全应用程序。
常量
// DES块大小(以字节为单位)
const BlockSize = 8
func NewCipher(key []byte) (cipher.Block, error)
NewCipher创建并返回一个新的cipher.Block。
参数 key: des对称加密使用的密码, 密码长度为64bit, 即8byte
func NewTripleDESCipher(key []byte) (cipher.Block, error)
NewTripleDESCipher创建并返回一个新的cipher.Block。
// 一个简单例子
func main() {
dst := DesEncrypt_CBC([]byte("12345"), []byte("99999999"))
DesDecrypt_CBC(dst, []byte("99999999"))
}
func DesEncrypt_CBC(src, key []byte) []byte {
// 1. 生成一个底层使用DES加/解密的Block接口对象
block, err := des.NewCipher(key)
if err != nil {
panic(err)
}
src = PKCS5Padding(src, block.BlockSize())
tmp := []byte("helloAAA")
// 2. 创建一个密码分组为CBC模式, 底层使用Block加密的BlockMode接口对象
blockMode := cipher.NewCBCEncrypter(block, tmp)
dst := make([]byte, len(src))
// 3. 使用cipher包的BlockMode接口对象对数据进行加/解密
blockMode.CryptBlocks(dst, src)
fmt.Printf("加密之后的数据:%v\n", dst)
return dst
}
func DesDecrypt_CBC(src, key []byte) []byte {
block, err := des.NewCipher(key)
if err != nil {
panic(err)
}
tmp := []byte("helloAAA")
blockMode := cipher.NewCBCDecrypter(block, tmp)
dst := make([]byte, len(src))
blockMode.CryptBlocks(dst, src)
dst = PKCS5UnPadding(dst)
fmt.Printf("解密之后的数据:%s\n", dst)
return dst
}
func PKCS5UnPadding(dst []byte) []byte {
length := len(dst)
count := int(dst[length-1])
return dst[:length-count]
}
func PKCS5Padding(src []byte, size int) []byte {
if len(src)%size == 0 {
return src
}
padding := size - (len(src) % size)
padText := bytes.Repeat([]byte{byte(padding)}, padding)
newText := append(src, padText...)
return newText
}
20.3 cipher
包 cipher 实现了标准的块密码模式,可以包裹在低级块密码实现的周围
类型
Block
type Block interface {
// BlockSize returns the cipher's block size.
BlockSize() int
// Encrypt encrypts the first block in src into dst.
// Dst and src must overlap entirely or not at all.
Encrypt(dst, src []byte)
// Decrypt decrypts the first block in src into dst.
// Dst and src must overlap entirely or not at all.
Decrypt(dst, src []byte)
}
Block 表示使用给定密钥的块密码的实现。它提供加密或解密单个块的功能。模式实现将该功能扩展到块流。
BlockMode
type BlockMode interface {
// BlockSize returns the mode's block size.
BlockSize() int
// CryptBlocks encrypts or decrypts a number of blocks. The length of
// src must be a multiple of the block size. Dst and src must overlap
// entirely or not at all.
//
// If len(dst) < len(src), CryptBlocks should panic. It is acceptable
// to pass a dst bigger than src, and in that case, CryptBlocks will
// only update dst[:len(src)] and will not touch the rest of dst.
//
// Multiple calls to CryptBlocks behave as if the concatenation of
// the src buffers was passed in a single run. That is, BlockMode
// maintains state and does not reset at each CryptBlocks call.
CryptBlocks(dst, src []byte)
}
BlockMode表示以基于块的模式(CBC、ECB等)运行的块密码。
20.3.1 NewCBCEncrypter()
func NewCBCEncrypter(b Block, iv []byte) BlockMode
NewCBCEncrypter返回一个 BlockMode ,该模式使用给定的区块以加密区块链模式进行加密。iv的长度必须与Block的块大小相同。
20.4 aex
// AES块大小(以字节为单位)
const BlockSize = 16
20.4.1 NewCipher()
func NewCipher(key []byte) (cipher.Block, error)
NewCipher创建并返回一个新的cipher.Block。key参数应为AES密钥,可以是16、24或32字节,以选择AES-128、AES-192或AES-256。
20.5 RSA
包 rsa实现PKCS #1和rfc8017中指定的rsa加密。
RSA是一个单一的基本操作,在这个包中用于实现公钥加密或公钥签名。
类型
PrivateKey
// PrivateKey表示RSA密钥
type PrivateKey struct {
PublicKey // public part.
D *big.Int // private exponent
Primes []*big.Int // prime factors of N, has >= 2 elements.
// Precomputed contains precomputed values that speed up private
// operations, if available.
Precomputed PrecomputedValues
}
20.5.1 GenerateKey()
func GenerateKey(random io.Reader, bits int) (*PrivateKey, error)
GenerateKey使用随机源random(例如crypto/rand.Reader)生成给定比特大小的RSA密钥对。
// 参数bits: 指定生成的秘钥的长度, 单位: bit
func RsaGenKey(bits int) error {
// 生成私钥
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return err
}
derStream := x509.MarshalPKCS1PrivateKey(privateKey)
block := pem.Block{Type: "RSA PRIVATE KEY", Bytes: derStream}
file, err := os.Create("private.pem")
if err != nil {
return err
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
fmt.Println("关闭文件失败")
}
}(file)
err = pem.Encode(file, &block)
if err != nil {
return err
}
// 生成公钥
publicKey := privateKey.PublicKey
derStream = x509.MarshalPKCS1PublicKey(&publicKey)
block1 := pem.Block{Type: "RSA PUBLIC KEY", Bytes: derStream}
file1, err := os.Create("public.pem")
if err != nil {
return err
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
fmt.Println("关闭文件失败")
}
}(file1)
err = pem.Encode(file1, &block1)
if err != nil {
return err
}
return nil
}
20.5.2 EncryptPKCS1v15()
func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error)
EncryptPKCS1v15使用RSA和pkcs# 1 v1.5的填充方案对给定的消息进行加密。该消息的长度必须不超过公共模的长度减去11字节。
使用随机参数作为熵源,以确保对同一消息加密两次不会产生相同的密文。
警告:使用此函数加密会话密钥以外的明文是危险的。在新协议中使用RSA OAEP。
20.5.3 DecryptPKCS1v15()
func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error)
DecryptPKCS1v15使用RSA和pkcs# 1 v1.5的填充方案解密明文。如果random != nil,则使用RSA盲法来避免定时侧通道攻击。
注意,这个函数是否返回错误会透露秘密信息。如果攻击者可以使该函数重复运行,并了解每个实例是否返回错误,那么他们就可以像拥有私钥一样解密和伪造签名。参见DecryptPKCS1v15SessionKey了解解决这个问题的方法。
func RSAEncrypt(src []byte, fileName string) []byte {
openFile, err := os.Open(fileName)
if err != nil {
return nil
}
fileInfo, _ := openFile.Stat()
allText := make([]byte, fileInfo.Size())
openFile.Read(allText)
openFile.Close()
block, _ := pem.Decode(allText)
if block == nil {
return nil
}
pubInterface, err := x509.ParsePKCS1PublicKey(block.Bytes)
if err != nil {
return nil
}
result, err := rsa.EncryptPKCS1v15(rand.Reader, pubInterface, src)
return result
}
func RSADecrypt(src []byte, fileName string) []byte {
openFile, err := os.Open(fileName)
if err != nil {
return nil
}
fileInfo, _ := openFile.Stat()
allText := make([]byte, fileInfo.Size())
openFile.Read(allText)
openFile.Close()
block, _ := pem.Decode(allText)
if block == nil {
return nil
}
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil
}
result, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, src)
return result
}
20.5.4 SignPKCS1v15()
func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error)
SignPKCS1v15使用RSA pkcs# 1 v1.5中的RSASSA-PKCS1-V1_5-SIGN计算散列签名。注意,hashed
必须是使用给定哈希函数对输入消息进行哈希的结果。如果 hash 为0,则hashed 直接被签名。除了互操作性,这是不可取的。
如果random不是nil,那么RSA盲化将被用来避免定时侧信道攻击(iming side-channel attacks.)。
这个函数是确定的。因此,如果可能的消息集很小,攻击者可能能够构建从消息到签名的映射并识别签名消息。和以往一样,签名提供的是真实性,而不是保密性。
20.5.5 VerifyPKCS1v15()
func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error
VerifyPKCS1v1 5验证RSA PKCS #1 v1.5签名。hashed 是使用给定的散列函数对输入消息进行散列的结果,sig 是签名。有效的签名是通过返回 nil 错误来表示的。如果hash 为零,则直接使用hashed 。除了互操作性,这是不可取的。
20.6 x509
包 x509 解析x .509编码的密钥和证书
20.6.1 MarshalPKCS1PrivateKey()
func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte
MarshalPKCS1PrivateKey 将RSA私钥转换为pkcs# 1, ASN.1 DER形式。
这种密钥通常编码在“RSA PRIVATE key”类型的PEM块中。对于更灵活的密钥格式,它不是RSA特定的,使用MarshalPKCS8PrivateKey。
20.6.2 MarshalPKCS8PrivateKey()
func MarshalPKCS8PrivateKey(key any) ([]byte, error)
MarshalPKCS8PrivateKey将私钥转换为pkcs# 8, ASN.1 DER形式。
目前支持的密钥类型有:*rsa。PrivateKey * ecdsa。PrivateKey ed25519.PrivateKey。不支持的密钥类型会导致错误
这类密钥通常编码在"PRIVATE KEY"的PEM块类型中。
20.6.3 MarshalPKCS1PublicKey()
func MarshalPKCS1PublicKey(key *rsa.PublicKey) []byte
MarshalPKCS1PublicKey converts an RSA public key to PKCS #1, ASN.1 DER form.
This kind of key is commonly encoded in PEM blocks of type “RSA PUBLIC KEY”.
20.6.4 ParsePKCS1PublicKey()
func ParsePKCS1PublicKey(der []byte) (*rsa.PublicKey, error)
ParsePKCS1PublicKey解析PKCS #1, ASN.1 DER格式的RSA公钥。
This kind of key is commonly encoded in PEM blocks of type “RSA PUBLIC KEY”.
20.7 ecdsa
包ecdsa实现了FIPS 186-4和SEC 1 2.0版本中定义的椭圆曲线数字签名算法(Elliptic Curve Digital Signature Algorithm)。
这个包生成的签名不是确定性的,但是熵与私钥和消息混合在一起,在随机源失败的情况下实现了相同级别的安全性。
类型
PrivateKey
type PrivateKey struct {
PublicKey
D *big.Int
}
PrivateKey 表示ECDSA私钥
20.7.1 GenerateKey()
func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error)
GenerateKey 生成一个公钥私钥对。
20.7.2 SignASN1()
func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error)
SignASN1使用私钥priv签署一个哈希(这应该是一个很大的消息的哈希)。如果哈希比私钥的曲线顺序的位长长,哈希将被截断到这个长度。它返回ASN.1编码的签名
20.7.2 VerifyASN1()
func VerifyASN1(pub *PublicKey, hash, sig []byte) bool
VerifyASN1使用公钥pub验证散列的ASN.1编码签名sig。它的返回值记录签名是否有效
20.8 elliptic
包 elliptic 实现了素数域上标准的NIST P-224, P-256, P-384和P-521椭圆曲线。
类型
Curve
type Curve interface {
// Params returns the parameters for the curve.
Params() *CurveParams
// IsOnCurve reports whether the given (x,y) lies on the curve.
IsOnCurve(x, y *big.Int) bool
// Add returns the sum of (x1,y1) and (x2,y2)
Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)
// Double returns 2*(x,y)
Double(x1, y1 *big.Int) (x, y *big.Int)
// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)
// ScalarBaseMult returns k*G, where G is the base point of the group
// and k is an integer in big-endian form.
ScalarBaseMult(k []byte) (x, y *big.Int)
}
Curve 表示A =-3的简形式Weierstrass曲线
当输入不是曲线上的一个点时,Add、Double和ScalarMult的行为是未定义的。
注意,虽然可以通过Add、Double、ScalarMult或ScalarBaseMult(但不能通过Unmarshal或UnmarshalCompressed函数)返回无穷大处的常规点(0,0),但曲线上不考虑它。
20.8.1 P256()
func P256() Curve
P256返回一个实现NIST P-256 (FIPS 186-3, D.2.3节)的曲线,也称为secp256r1或prime256v1。这条曲线的 CurveParams.Name 是“P-256”。
多次调用此函数将返回相同的值,因此它可以用于相等检查和开关语句。
加密操作是使用恒定时间算法实现的。
20.9 rand
包 rand 实现了一个加密安全的随机数生成器
变量
var Reader io.Reader
Reader是加密安全随机数生成器的全局共享实例。
20.9.1 Read()
func Read(b []byte) (n int, err error)
Read 是一个通过使用 io.ReadFull 调用Reader.Read的辅助函数。返回时,当且仅当err == nil
时,n == len(b)
20.9.2 Prime()
func Prime(rand io.Reader, bits int) (*big.Int, error)
Prime 返回一个给定比特长度的高概率质数数。对于rand.Read返回的任何错误,Prime都将返回错误。或 bits < 2.
20.9.3 Int()
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)
Int 返回一个统一的随机值[0,max)。如果max <= 0,则会出现恐慌。
20.10 md5
Package md5实现了RFC 1321中定义的md5哈希算法。
MD5在密码学上被破解了,不应该用于安全应用程序。
常量
// MD5的块大小,以字节为单位
const BlockSize = 64
// MD5校验和的大小,以字节为单位
const Size = 16
20.10.1 Sum()
func Sum(data []byte) [Size]byte
Sum返回数据的MD5校验和。
20.10.2 New()
func New() hash.Hash
New返回一个新的 hash.Hash用于计算MD5校验和。Hash 还实现了encoding.BinaryMarshaler和encoding.BinaryUnmarshaler来封送散列的内部状态。
20.11 sha1
包 sha1实现了RFC 3174中定义的SHA-1哈希算法。
MD5在密码学上被破解了,不应该用于安全应用程序。
func New() hash.Hash
func Sum(data []byte) [Size]byte
func main() {
str := []byte("hello world")
fmt.Printf("第一种方式:%x\n", sha1.Sum(str))
hash := sha1.New()
hash.Write(str)
fmt.Printf("第二种方式:%x\n", hash.Sum(nil))
}
/* 输出:
第一种方式:2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
第二种方式:2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
*/
20.12 hmac
包 hmac 实现了美国联邦信息处理标准出版物198中定义的密钥哈希消息认证码(Keyed-Hash Message Authentication Code,hmac)。HMAC是一种使用密钥对消息进行签名的加密散列。接收方通过使用相同的密钥重新计算哈希来验证哈希。
接收机应该小心使用 Equal 来比较 mac,以避免计时侧通道:
// ValidMAC reports whether messageMAC is a valid HMAC tag for message.
func ValidMAC(message, messageMAC, key []byte) bool {
mac := hmac.New(sha256.New, key)
mac.Write(message)
expectedMAC := mac.Sum(nil)
return hmac.Equal(messageMAC, expectedMAC)
}
20.12.1 New()
func New(h func() hash.Hash, key []byte) hash.Hash
New 使用给定的散列和密钥返回一个新的 HMAC 散列。sha256 等新函数。crypto/sha256 New 函数像 sha256.New 可以用作 h。h每次被调用时都必须返回一个新的Hash。注意,与标准库中的其他哈希实现不同,返回的哈希不实现encoding.BinaryMarshaler或encoding.BinaryUnmarshaler。
20.12.2 Equal()
func Equal(mac1, mac2 []byte) bool
Equal在不泄露时间信息的情况下比较两个mac是否相等。
func main() {
src := []byte("123456")
key := []byte("aaaaaa")
hmac := GenerateHMAC(src, key)
verifyHMAC := VerifyHMAC(hmac, src, key)
fmt.Println(verifyHMAC)
}
func GenerateHMAC(src, key []byte) []byte {
myHmac := hmac.New(sha256.New, key)
myHmac.Write(src)
result := myHmac.Sum(nil)
return result
}
func VerifyHMAC(res, src, key []byte) bool {
myHmac := hmac.New(sha256.New, key)
myHmac.Write(src)
result := myHmac.Sum(nil)
return hmac.Equal(res, result)
}
PKCS
PKCS 全称是 Public-Key Cryptography Standards ,是由 RSA 实验室与其它安全系统开发商为促进公钥密 码的发展而制订的一系列标准。
RSA
现在使用最广泛 的公钥密码算法一一RSA。 RSA是一种非对称加密算法,它的名字是由它的三位开发者,即 RonRivest、AdiShamir和LeonardAdleman 的姓氏的首字母组成的(Rivest-Shamir-Leonard)。
RSA可以被用于非对称加密和数字签名。
1983年,RSA公司为RSA算法在美国取得了专利,但现在该专利已经过期
RSA加密
也就是说,RSA的密文是对代表明文的数字的E次方求modN的结果。换句话说,就是将明文自己做E次乘 法,然后将其结果除以N求余数,这个余数就是密文。
加密公式中出现的两个数一一一E和N,到底都是什么数呢?RSA的加密是求明文的E次方modN,因此 只要知道E和N这两个数,任何人都可以完成加密的运算。所以说,E和N是RSA加密的密钥,也就是说,E和 N的组合就是公钥。们一般会写成 “公钥是(E,N)” 或者 “公钥是{E, N}" 这样的形式
RSA解密
对表示密文的数字的D次方求modN就可以得到明文。换句话说,将密文自己做D次乘法,再对其 结果除以N求余数,就可以得到明文。
这里所使用的数字N和加密时使用的数字N是相同的。数D和数N组合起来就是RSA的解密密钥,因此D和N的 组合就是私钥。
DER编码和ASN.1
DER编码和ASN.1
DER
(Distinguished Encoding Rules,可辨别编码规则)。
ASN.1
抽象语法标记(Abstract Syntax Notation One)
ASN.1是一种 ISO/ITU-T 标准,描述了一种对数据进行表示、编码、传输和解码的数据格式。
二十一、 bytes
包
包 bytes 实现了操作byte 切片的功能。它类似于strings 包的功能。
类型
Buffer
type Buffer struct {
// contains filtered or unexported fields
}
Buffer是具有读和写方法的可变大小字节缓冲区。Buffer的零值是一个可以使用的空缓冲区。
Write()
func (b *Buffer) Write(p []byte) (n int, err error)
Write将p的内容追加到缓冲区,根据需要增加缓冲区。返回值n是p的长度;Err总是nil。如果缓冲区变得太大,Write会恐慌使用ErrTooLarge。
Read()
func (b *Buffer) Read(p []byte) (n int, err error)
Read从缓冲区中读取下一个len(p)
字节或直到缓冲区耗尽。返回值n是读取的字节数。如果缓冲区没有数据返回,则err为io.EOF(除非len§为零);否则为nil。
Grow()
func (b *Buffer) Grow(n int)
Grow增加缓冲区的容量,如有必要,以保证另一个n字节的空间。在Grow(n)之后,至少有n个字节可以写入缓冲区,而无需再进行分配。如果n是负数,Grow就会惊慌失措。如果缓冲区不能增长,它将恐慌ErrTooLarge。
21.1 Join()
func Join(s [][]byte, sep []byte) []byte
Join连接s的元素以创建一个新的字节切片。分隔符 sep 被放置在结果片中的元素之间。
21.2 Equal()
func Equal(a, b []byte) bool
Equal 报告a和b是否相同的长度和包含相同的字节。nil参数相当于一个空切片。
21.3 Repeat()
func Repeat(b []byte, count int) []byte
Repeat返回一个由b的count个副本组成的新字节片。
如果count为负数,或者(len(b) * count)的结果溢出,则会出现恐慌。
二十二、binary
包
包二进制实现了数字和字节序列之间的简单转换以及变量的编码和解码。
二十三、math
包
23.1 big
包big实现任意精度的算术(大数字)。支持以下数字类型:
Int signed integers
Rat rational numbers
Float floating-point numbers
Int、Rat或Float类型的零值对应于0。因此,新的值可以用通常的方式声明,并且表示0时无需进一步初始化:
var x Int // &x is an *Int of value 0
var r = &Rat{} // r is a *Rat of value 0
y := new(Float) // y is a *Float of value 0
类型
1. Int
type Int struct {
// contains filtered or unexported fields
}
Int表示带符号的多精度整数。Int类型的零值表示值0。
func (z *Int) SetString(s string, base int) (*Int, bool)
SetString 将z设置为s的值,用给定的基数解释,并返回z和一个表示成功的布尔值。
整个字符串(不仅仅是前缀)必须有效才能成功。如果SetString失败,z的值是未定义的,但返回值是nil。
func (z *Int) SetBytes(buf []byte) *Int
SetBytes 将buf解释为大端序无符号整数的字节,将z设置为该值,并返回z。
func (x *Int) Cmp(y *Int) (r int)
Cmp compares x and y and returns:
-1 if x < y
0 if x == y
+1 if x > y
二十四、gob
包
二十五、fs
包
包 fs 定义到文件系统的基本接口。文件系统可以由主机操作系统提供,也可以由其他包提供。
类型
FileInfo
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() any // underlying data source (can return nil)
}
FileInfo 描述了一个文件,由Stat返回。
二十六、hash
包
包 hash 为哈希函数提供接口。
类型
Hash
type Hash interface {
// Write (via the embedded io.Writer interface) adds more data to the running hash.
// It never returns an error.
io.Writer
// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
Sum(b []byte) []byte
// Reset resets the Hash to its initial state.
Reset()
// Size returns the number of bytes Sum will return.
Size() int
// BlockSize returns the hash's underlying block size.
// The Write method must be able to accept any amount
// of data, but it may operate more efficiently if all writes
// are a multiple of the block size.
BlockSize() int
}
哈希是所有哈希函数实现的公共接口
func main() {
str := []byte("hello world")
fmt.Printf("第一种方式:%x\n", md5.Sum(str))
hash := md5.New()
hash.Write(str)
fmt.Printf("第二种方式:%x\n", hash.Sum(nil))
}
/* 输出:
第一种方式:5eb63bbbe01eeed093cb22bb8f5acdc3
第二种方式:5eb63bbbe01eeed093cb22bb8f5acdc3
*/
Hash32
type Hash32 interface {
Hash
Sum32() uint32
}
Hash32是由所有32位散列函数实现的公共接口。
Hash64
type Hash64 interface {
Hash
Sum64() uint64
}
Hash64是由所有64位散列函数实现的公共接口。