- aes
- cipher
- des
- dsa
- ecdsa
- elliptic
crypto
crypto包搜集了常用的密码(算法)常量。
type PublicKey
type PublicKey interface{}
代表一个使用未指定算法的公钥。
type PrivateKey
type PrivateKey interface{}
代表一个使用未指定算法的私钥。
type Hash
type Hash uint
Hash用来识别/标识另一个包里实现的加密函数。
const (
MD4 Hash = 1 + iota // 导入code.google.com/p/go.crypto/md4
MD5 // 导入crypto/md5
SHA1 // 导入crypto/sha1
SHA224 // 导入crypto/sha256
SHA256 // 导入crypto/sha256
SHA384 // 导入crypto/sha512
SHA512 // 导入crypto/sha512
MD5SHA1 // 未实现;MD5+SHA1用于TLS RSA
RIPEMD160 // 导入code.google.com/p/go.crypto/ripemd160
)
func (Hash) Available
func (h Hash) Available() bool
报告是否有hash函数注册到该标识值。
func (Hash) Size
func (h Hash) Size() int
返回给定hash函数返回值的字节长度。
func (Hash) New
func (h Hash) New() hash.Hash
创建一个使用给定hash函数的hash.Hash接口,如果该标识值未注册hash函数,将会panic。
func RegisterHash
func RegisterHash(h Hash, f func() hash.Hash)
注册一个返回给定hash接口实例的函数,并指定其标识值,该函数应在实现hash接口的包的init函数中调用。
aes
aes包实现了AES加密算法,参见U.S. Federal Information Processing Standards Publication 197。
Constants
const BlockSize = 16
AES字节块大小。
type KeySizeError
type KeySizeError int
func (KeySizeError) Error
func (k KeySizeError) Error() string
func NewCipher
func NewCipher(key []byte) (cipher.Block, error)
创建一个cipher.Block接口。参数key为密钥,长度只能是16、24、32字节,用以选择AES-128、AES-192、AES-256。
// 填充
func padding(src []byte, blockSize int) []byte {
padNum := blockSize - len(src) % blockSize
pad := bytes.Repeat([]byte{byte(padNum)}, padNum)
fmt.Println(string(pad))
return append(src, pad...)
}
// 去掉填充
func unpadding(src []byte) []byte {
n := len(src)
unPadNum := int(src[n-1])
return src[:n-unPadNum]
}
// 加密
func encryptAES(src []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
src = padding(src, block.BlockSize())
fmt.Println(len(src))
blockMode := cipher.NewCBCEncrypter(block, key)
blockMode.CryptBlocks(src, src)
return src, nil
}
// 解密
func decryptAES(src []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, key)
blockMode.CryptBlocks(src, src)
src = unpadding(src)
return src, nil
}
cipher
cipher包实现了多个标准的用于包装底层块加密算法的加密算法实现。
type Block
type Block interface {
// 返回加密字节块的大小
BlockSize() int
// 加密src的第一块数据并写入dst,src和dst可指向同一内存地址
Encrypt(dst, src []byte)
// 解密src的第一块数据并写入dst,src和dst可指向同一内存地址
Decrypt(dst, src []byte)
}
Block接口代表一个使用特定密钥的底层块加/解密器。它提供了加密和解密独立数据块的能力。
type BlockMode
type BlockMode interface {
// 返回加密字节块的大小
BlockSize() int
// 加密或解密连续的数据块,src的尺寸必须是块大小的整数倍,src和dst可指向同一内存地址
CryptBlocks(dst, src []byte)
}
BlockMode接口代表一个工作在块模式(如CBC、ECB等)的加/解密器。
func NewCBCEncrypter
func NewCBCEncrypter(b Block, iv []byte) BlockMode
返回一个密码分组链接模式的、底层用b加密的BlockMode接口,初始向量iv的长度必须等于b的块尺寸。
func NewCBCDecrypter
func NewCBCDecrypter(b Block, iv []byte) BlockMode
返回一个密码分组链接模式的、底层用b解密的BlockMode接口,初始向量iv必须和加密时使用的iv相同。
type Stream
type Stream interface {
// 从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
XORKeyStream(dst, src []byte)
}
Stream接口代表一个流模式的加/解密器。
func NewCFBEncrypter
func NewCFBEncrypter(block Block, iv []byte) Stream
返回一个密码反馈模式的、底层用block加密的Stream接口,初始向量iv的长度必须等于block的块尺寸。
func NewCFBDecrypter
func NewCFBDecrypter(block Block, iv []byte) Stream
返回一个密码反馈模式的、底层用block解密的Stream接口,初始向量iv必须和加密时使用的iv相同。
func NewOFB
func NewOFB(b Block, iv []byte) Stream
返回一个输出反馈模式的、底层采用b生成key流的Stream接口,初始向量iv的长度必须等于b的块尺寸。
func NewCTR
func NewCTR(block Block, iv []byte) Stream
返回一个计数器模式的、底层采用block生成key流的Stream接口,初始向量iv的长度必须等于block的块尺寸。
type StreamReader
type StreamReader struct {
S Stream
R io.Reader
}
将一个Stream与一个io.Reader接口关联起来,Read方法会调用XORKeyStream方法来处理获取的所有切片。
func (StreamReader) Read
func (r StreamReader) Read(dst []byte) (n int, err error)
type StreamWriter
type StreamWriter struct {
S Stream
W io.Writer
Err error // unused
}
将一个Stream与一个io.Writer接口关联起来,Write方法会调用XORKeyStream方法来处理提供的所有切片。如果Write方法返回的n小于提供的切片的长度,则表示StreamWriter不同步,必须丢弃。StreamWriter没有内建的缓存,不需要调用Close方法去清空缓存。
func (StreamWriter) Write
func (w StreamWriter) Write(src []byte) (n int, err error)
func (StreamWriter) Close
func (w StreamWriter) Close() error
如果w.W字段实现了io.Closer接口,本方法会调用其Close方法并返回该方法的返回值;否则不做操作返回nil。
type AEAD
type AEAD interface {
// 返回提供给Seal和Open方法的随机数nonce的字节长度
NonceSize() int
// 返回原始文本和加密文本的最大长度差异
Overhead() int
// 加密并认证明文,认证附加的data,将结果添加到dst,返回更新后的切片。
// nonce的长度必须是NonceSize()字节,且对给定的key和时间都是独一无二的。
// plaintext和dst可以是同一个切片,也可以不同。
Seal(dst, nonce, plaintext, data []byte) []byte
// 解密密文并认证,认证附加的data,如果认证成功,将明文添加到dst,返回更新后的切片。
// nonce的长度必须是NonceSize()字节,nonce和data都必须和加密时使用的相同。
// ciphertext和dst可以是同一个切片,也可以不同。
Open(dst, nonce, ciphertext, data []byte) ([]byte, error)
}
AEAD接口是一种提供了使用关联数据进行认证加密的功能的加密模式。
func NewGCM
func NewGCM(cipher Block) (AEAD, error)
函数用迦洛瓦计数器模式包装提供的128位Block接口,并返回AEAD接口。
des
des包实现了DES标准和TDEA算法,参见U.S. Federal Information Processing Standards Publication 46-3。
Constants
const BlockSize = 8
DES字节块的大小。
type KeySizeError
type KeySizeError int
func (KeySizeError) Error
func (k KeySizeError) Error() string
func NewCipher
func NewCipher(key []byte) (cipher.Block, error)
创建并返回一个使用DES算法的cipher.Block接口。
func NewTripleDESCipher
func NewTripleDESCipher(key []byte) (cipher.Block, error)
创建并返回一个使用TDEA算法的cipher.Block接口。
// 填充
func padding(src []byte, blockSize int) []byte {
padNum := blockSize - len(src) % blockSize
pad := bytes.Repeat([]byte{byte(padNum)}, padNum)
fmt.Println(string(pad))
return append(src, pad...)
}
// 去掉填充
func unpadding(src []byte) []byte {
n := len(src)
unPadNum := int(src[n-1])
return src[:n-unPadNum]
}
// 加密
func encryptDES(src []byte, key []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
src = padding(src, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, key)
blockMode.CryptBlocks(src, src)
return src, nil
}
// 解密
func decryptDES(src []byte, key []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, key)
blockMode.CryptBlocks(src, src)
src = unpadding(src)
return src, nil
}
func main() {
d := []byte("hello world")
key := []byte("12345678")
fmt.Println("加密前:", string(d))
x1, err := encryptDES(d, key)
if err != nil {
fmt.Println(err)
}
fmt.Println("加密后:", string(x1))
x2, err := decryptDES(x1, key)
if err != nil {
fmt.Println(err)
}
fmt.Println("解密后:", string(x2))
}
dsa
dsa包实现FIPS 186-3定义的数字签名算法(Digital Signature Algorithm),即DSA算法
Variables
var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key")
非法公钥,FIPS标准的公钥格式是很严格的,但有些实现没这么严格,使用这些实现的公钥时,就会导致这个错误。
type ParameterSizes
type ParameterSizes int
是DSA参数中的质数可以接受的字位长度的枚举,参见FIPS 186-3 section 4.2。
const (
L1024N160 ParameterSizes = iota
L2048N224
L2048N256
L3072N256
)
type Parameters
type Parameters struct {
P, Q, G *big.Int
}
Parameters代表密钥的域参数,这些参数可以被一组密钥共享,Q的字位长度必须是8的倍数。
type PublicKey
type PublicKey struct {
Parameters
Y *big.Int
}
PublicKey代表一个DSA公钥。
type PrivateKey
type PrivateKey struct {
PublicKey
X *big.Int
}
PrivateKey代表一个DSA私钥。
func GenerateKey
func GenerateParameters
func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) (err error)
GenerateParameters函数随机设置合法的参数到params。即使机器很快,函数也可能会花费很多时间来生成参数。
func GenerateKey(priv *PrivateKey, rand io.Reader) error
GenerateKey生成一对公钥和私钥;priv.PublicKey.Parameters字段必须已经(被GenerateParameters函数)设置了合法的参数。
func Sign
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error)
使用私钥对任意长度的hash值(必须是较大信息的hash结果)进行签名,返回签名结果(一对大整数)。私钥的安全性取决于密码读取器的熵度(随机程度)。
注意根据FIPS 186-3 section 4.6的规定,hash必须被截断到亚组的长度,本函数是不会自己截断的。
func Verify
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool
使用公钥认证hash和两个大整数r、s构成的签名,报告签名是否合法。
注意根据FIPS 186-3 section 4.6的规定,hash必须被截断到亚组的长度,本函数是不会自己截断的。
func main() {
// parameters 是私钥的参数
var param dsa.Parameters
// L1024N160是一个枚举,根据L1024N160来决定私钥的长度(L N)
dsa.GenerateParameters(¶m, rand.Reader, dsa.L1024N160)
// 定义私钥的变量
var privateKey dsa.PrivateKey
// 设置私钥的参数
privateKey.Parameters = param
// 生成密钥对
dsa.GenerateKey(&privateKey, rand.Reader)
// 公钥是存在在私钥中的,从私钥中读取公钥
publicKey := privateKey.PublicKey
message := []byte("hello,dsa签名")
fmt.Println(publicKey)
fmt.Println(privateKey)
// 进入签名操作
r, s, _ := dsa.Sign(rand.Reader, &privateKey, message)
// 进入验证
flag := dsa.Verify(&publicKey, message, r, s)
if flag {
fmt.Println("数据未被修改")
} else {
fmt.Println("数据被修改")
}
flag = dsa.Verify(&publicKey, []byte("hello"), r, s)
if flag {
fmt.Println("数据未被修改")
} else {
fmt.Println("数据被修改")
}
}
ecdsa
ecdsa包实现了椭圆曲线数字签名算法,参见FIPS 186-3。
type PublicKey
type PublicKey struct {
elliptic.Curve
X, Y *big.Int
}
PrivateKey代表一个ECDSA公钥。
type PrivateKey
type PrivateKey struct {
PublicKey
D *big.Int
}
PrivateKey代表一个ECDSA私钥。
func GenerateKey
GenerateKey函数生成一对
func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error)
公钥/私钥。
func Sign
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error)
使用私钥对任意长度的hash值(必须是较大信息的hash结果)进行签名,返回签名结果(一对大整数)。私钥的安全性取决于密码读取器的熵度(随机程度)。
func Verify
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool
使用公钥验证hash值和两个大整数r、s构成的签名,并返回签名是否合法。
elliptic
elliptic包实现了几条覆盖素数有限域的标准椭圆曲线。
type Curve
type Curve interface {
// Params返回椭圆曲线的参数
Params() *CurveParams
// IsOnCurve判断一个点是否在椭圆曲线上
IsOnCurve(x, y *big.Int) bool
// 返回点(x1,y1)和点(x2,y2)相加的结果
Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)
// 返回2*(x,y),即(x,y)+(x,y)
Double(x1, y1 *big.Int) (x, y *big.Int)
// k是一个大端在前格式的数字,返回k*(Bx,By)
ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)
// k是一个大端在前格式的数字,返回k*G,G是本椭圆曲线的基点
ScalarBaseMult(k []byte) (x, y *big.Int)
}
Curve代表一个短格式的Weierstrass椭圆曲线,其中a=-3。
Weierstrass椭圆曲线的格式:y2 = x3 + a*x + b
func P224
func P224() Curve
返回一个实现了P-224的曲线。(参见FIPS 186-3, section D.2.2)
func P256
func P256() Curve
返回一个实现了P-256的曲线。(参见FIPS 186-3, section D.2.3)
func P384
func P384() Curve
返回一个实现了P-384的曲线。(参见FIPS 186-3, section D.2.4)
func P521
func P521() Curve
返回一个实现了P-512的曲线。(参见FIPS 186-3, section D.2.5)
type CurveParams
type CurveParams struct {
P *big.Int // 决定有限域的p的值(必须是素数)
N *big.Int // 基点的阶(必须是素数)
B *big.Int // 曲线公式的常量(B!=2)
Gx, Gy *big.Int // 基点的坐标
BitSize int // 决定有限域的p的字位数
}
CurveParams包含一个椭圆曲线的所有参数,也可提供一般的、非常数时间实现的椭圆曲线。
func (*CurveParams) Params
func (curve *CurveParams) Params() *CurveParams
func (*CurveParams) IsOnCurve
func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool
func (*CurveParams) Add
func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int)
func (*CurveParams) Double
func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int)
func (*CurveParams) ScalarMult
func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int)
func (*CurveParams) ScalarBaseMult
func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int)
func GenerateKey
func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error)
GenerateKey返回一个公钥/私钥对。priv是私钥,而(x,y)是公钥。密钥对是通过提供的随机数读取器来生成的,该io.Reader接口必须返回随机数据。
func Marshal
func Marshal(curve Curve, x, y *big.Int) []byte
Marshal将一个点编码为ANSI X9.62指定的格式。
func Unmarshal
func Unmarshal(curve Curve, data []byte) (x, y *big.Int)
将一个Marshal编码后的点还原;如果出错,x会被设为nil。
有疑问加站长微信联系(非本文作者)