目录搜索
archivearchive/tararchive/zipbufiobufio(缓存)builtinbuiltin(内置包)bytesbytes(包字节)compresscompress/bzip2(压缩/bzip2)compress/flate(压缩/flate)compress/gzip(压缩/gzip)compress/lzw(压缩/lzw)compress/zlib(压缩/zlib)containercontainer/heap(容器数据结构heap)container/list(容器数据结构list)container/ring(容器数据结构ring)contextcontext(上下文)cryptocrypto(加密)crypto/aes(加密/aes)crypto/cipher(加密/cipher)crypto/des(加密/des)crypto/dsa(加密/dsa)crypto/ecdsa(加密/ecdsa)crypto/elliptic(加密/elliptic)crypto/hmac(加密/hmac)crypto/md5(加密/md5)crypto/rand(加密/rand)crypto/rc4(加密/rc4)crypto/rsa(加密/rsa)crypto/sha1(加密/sha1)crypto/sha256(加密/sha256)crypto/sha512(加密/sha512)crypto/subtle(加密/subtle)crypto/tls(加密/tls)crypto/x509(加密/x509)crypto/x509/pkix(加密/x509/pkix)databasedatabase/sql(数据库/sql)database/sql/driver(数据库/sql/driver)debugdebug/dwarf(调试/dwarf)debug/elf(调试/elf)debug/gosym(调试/gosym)debug/macho(调试/macho)debug/pe(调试/pe)debug/plan9obj(调试/plan9obj)encodingencoding(编码)encoding/ascii85(编码/ascii85)encoding/asn1(编码/asn1)encoding/base32(编码/base32)encoding/base64(编码/base64)encoding/binary(编码/binary)encoding/csv(编码/csv)encoding/gob(编码/gob)encoding/hex(编码/hex)encoding/json(编码/json)encoding/pem(编码/pem)encoding/xml(编码/xml)errorserrors(错误)expvarexpvarflagflag(命令行参数解析flag包)fmtfmtgogo/ast(抽象语法树)go/buildgo/constant(常量)go/doc(文档)go/format(格式)go/importergo/parsergo/printergo/scanner(扫描仪)go/token(令牌)go/types(类型)hashhash(散列)hash/adler32hash/crc32hash/crc64hash/fnvhtmlhtmlhtml/template(模板)imageimage(图像)image/color(颜色)image/color/palette(调色板)image/draw(绘图)image/gifimage/jpegimage/pngindexindex/suffixarrayioioio/ioutillogloglog/syslog(日志系统)mathmathmath/bigmath/bigmath/bitsmath/bitsmath/cmplxmath/cmplxmath/randmath/randmimemimemime/multipart(多部分)mime/quotedprintablenetnetnet/httpnet/httpnet/http/cginet/http/cookiejarnet/http/fcginet/http/httptestnet/http/httptracenet/http/httputilnet/http/internalnet/http/pprofnet/mailnet/mailnet/rpcnet/rpcnet/rpc/jsonrpcnet/smtpnet/smtpnet/textprotonet/textprotonet/urlnet/urlososos/execos/signalos/userpathpathpath/filepath(文件路径)pluginplugin(插件)reflectreflect(反射)regexpregexp(正则表达式)regexp/syntaxruntimeruntime(运行时)runtime/debug(调试)runtime/internal/sysruntime/pprofruntime/race(竞争)runtime/trace(执行追踪器)sortsort(排序算法)strconvstrconv(转换)stringsstrings(字符串)syncsync(同步)sync/atomic(原子操作)syscallsyscall(系统调用)testingtesting(测试)testing/iotesttesting/quicktexttext/scanner(扫描文本)text/tabwritertext/template(定义模板)text/template/parsetimetime(时间戳)unicodeunicodeunicode/utf16unicode/utf8unsafeunsafe
文字

  • import "crypto/cipher"

  • 概述

  • 索引

  • 示例

概述

加密包(Package cipher)实现了标准块密码模式,可以围绕低级块密码实现。请参阅http://csrc.nist.gov/groups/ST/toolkit/BCM/current_modes.html和NIST Special Publication

800-38A。

索引

  • type AEAD

  • func NewGCM(cipher Block) (AEAD, error)

  • func NewGCMWithNonceSize(cipher Block, size int) (AEAD, error)

  • type Block

  • type BlockMode

  • func NewCBCDecrypter(b Block, iv []byte) BlockMode

  • func NewCBCEncrypter(b Block, iv []byte) BlockMode

  • type Stream

  • func NewCFBDecrypter(block Block, iv []byte) Stream

  • func NewCFBEncrypter(block Block, iv []byte) Stream

  • func NewCTR(block Block, iv []byte) Stream

  • func NewOFB(b Block, iv []byte) Stream

  • type StreamReader

  • func (r StreamReader) Read(dst []byte) (n int, err error)

  • type StreamWriter

  • func (w StreamWriter) Close() error

  • func (w StreamWriter) Write(src []byte) (n int, err error)

示例

NewCBCDecrypter NewCBCEncrypter NewCFBDecrypter NewCFBEncrypter NewCTR NewGCM (Decrypt) NewGCM (Encrypt) NewOFB StreamReader StreamWriter

文件包

cbc.go cfb.go cipher.go ctr.go gcm.go io.go ofb.go xor.go

type AEAD

AEAD是一种密码模式,提供带有关联数据的认证加密。有关该方法的说明,请参阅

https://en.wikipedia.org/wiki/Authenticated_encryption
type AEAD interface {        // NonceSize返回必须传递给Seal的随机数的大小        // and Open.        NonceSize() int        // Overhead返回以下两者间的最大差异        // plaintext 和 its ciphertext.        Overhead() int        // 密封加密和验证明文,验证        // 附加数据并将结果附加到dst,并返回更新        // slice。 nonce必须是NonceSize()字节长且对所有人都是唯一的        // time, 对于给定的密钥。        //        // 明文和dst可能完全或根本不是别名。 重用        // 明文的加密输出存储,使用 plaintext[:0]作为dst。        Seal(dst, nonce, plaintext, additionalData []byte) []byte        // 打开解密并验证密文,验证密文        // 额外的数据,如果成功的话,附加结果明文        // 到dst,返回更新的片。 nonce必须是NonceSize()        // 字节长,它和附加数据必须匹配        // 值传递给Seal。        //        // 密文和dst可以完全混淆或根本不混淆。 重用        // 密文的解密输出存储,使用ciphertext [:0]作为dst。        //        // 即使该功能失败,dst的内容,直到其容量,        // 可能会被覆盖。        Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error)}

func NewGCM

func NewGCM(cipher Block) (AEAD, error)

NewGCM 返回给定的128-bit,以伽罗华计数器模式(Galois Counter Mode包装的分组密码,其标准随机数长度。

一般来说,这种 GCM 实施的 GHASH 操作不是一个固定时间。当硬件支持 AES 的系统上由 aes.NewCipher 创建底层 Block 时,则是个例外。有关详细信息,请参阅 crypto/aes 软件包文档。

示例(Decrypt)

package mainimport ("crypto/aes""crypto/cipher""encoding/hex""fmt")func main() {// 关键参数应该是AES密钥,16或32个字节// 选择 AES-128 或 AES-256。
	key := []byte("AES256Key-32Characters1234567890")
	ciphertext, _ := hex.DecodeString("1019aa66cd7c024f9efd0038899dae1973ee69427f5a6579eba292ffe1b5a260")

	nonce, _ := hex.DecodeString("37b8e8a308c354048d245f6d")

	block, err := aes.NewCipher(key)if err != nil {panic(err.Error())}

	aesgcm, err := cipher.NewGCM(block)if err != nil {panic(err.Error())}

	plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)if err != nil {panic(err.Error())}

	fmt.Printf("%s\n", plaintext)}

示例(Encrypt

package mainimport ("crypto/aes""crypto/cipher""crypto/rand""fmt""io")func main() {// 关键参数应该是AES密钥,16或32个字节// 选择AES-128或AES-256。
	key := []byte("AES256Key-32Characters1234567890")
	plaintext := []byte("exampleplaintext")

	block, err := aes.NewCipher(key)if err != nil {panic(err.Error())}// 由于存在重复的风险,请勿使用给定密钥使用超过2^32个随机值。
	nonce := make([]byte, 12)if _, err := io.ReadFull(rand.Reader, nonce); err != nil {panic(err.Error())}

	aesgcm, err := cipher.NewGCM(block)if err != nil {panic(err.Error())}

	ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)
	fmt.Printf("%x\n", ciphertext)}

func NewGCMWithNonceSize

func NewGCMWithNonceSize(cipher Block, size int) (AEAD, error)

NewGCMWithNonceSize 返回给定的 128 位,以 Galois 计数器模式包装的分组密码,它接受给定长度的随机数。

如果您需要与使用非标准随机数长度的现有密码系统兼容,请仅使用此功能。所有其他用户都应该使用 NewGCM,它更快,更耐滥用。

type Block

块表示使用给定密钥的分组密码的实现。它提供了加密或解密各个块的功能。模式实现将该能力扩展到块流。

type Block interface {        // BlockSize返回密码的块大小。        BlockSize() int        // 加密将src中的第一个块加密到dst中。        // Dst和src可能指向相同的内存。        Encrypt(dst, src []byte)        // 解密将src中的第一个块解密为dst。        // Dst和src可能指向相同的内存。        Decrypt(dst, src []byte)}

type BlockMode

BlockMode表示以基于块的模式运行的分组密码(CBC,ECB等)。

type BlockMode interface {        // BlockSize返回模式的块大小。        BlockSize() int        // CryptBlocks加密或解密一些块。 The length of        // src必须是块大小的倍数。 Dst和src可能指向        // 相同的内存。        CryptBlocks(dst, src []byte)}

func NewCBCDecrypter

func NewCBCDecrypter(b Block, iv []byte) BlockMode

NewCBCDecrypter 返回一个 BlockMode,它使用给定的Block 以密码块链接模式解密。iv 的长度必须与 Block 的块大小相同,并且必须与用于加密数据的 iv 相匹配。

示例

package mainimport ("crypto/aes""crypto/cipher""encoding/hex""fmt")func main() {
	key := []byte("example key 1234")
	ciphertext, _ := hex.DecodeString("f363f3ccdcb12bb883abf484ba77d9cd7d32b5baecb3d4b1b3e0e4beffdb3ded")

	block, err := aes.NewCipher(key)if err != nil {panic(err)}// IV需要独特,但不安全。 所以这很常见// 将其包括在密文的开头。if len(ciphertext) < aes.BlockSize {panic("ciphertext too short")}
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]// CBC模式总是在整个模块中工作。if len(ciphertext)%aes.BlockSize != 0 {panic("ciphertext is not a multiple of the block size")}

	mode := cipher.NewCBCDecrypter(block, iv)// 如果两个参数相同,CryptBlocks可以在原地工作。
	mode.CryptBlocks(ciphertext, ciphertext)// 如果原始plaintext长度不是块的倍数// 大小,填充将不得不在加密时添加,这将是// 在这一点删除。 有关示例,请参阅// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. 然而,// 至关重要的是要注意密文必须被认证(即通过// 使用crypto/hmac)解密之前,以避免创建// 一个填充oracle。

	fmt.Printf("%s\n", ciphertext)}

func NewCBCEncrypter

func NewCBCEncrypter(b Block, iv []byte) BlockMode

NewCBCEncrypter 返回一个 BlockMode,它使用给定的 Block 以密码块链接模式加密。iv 的长度必须与块的块大小相同。

示例

package mainimport ("crypto/aes""crypto/cipher""crypto/rand""fmt""io")func main() {
	key := []byte("example key 1234")
	plaintext := []byte("exampleplaintext")// CBC模式在块上工作,所以明文可能需要填充到块// 下一个整块。 有关这种填充的示例,请参阅// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. 这里,我们将// 假定 plaintext 已经是正确的长度。if len(plaintext)%aes.BlockSize != 0 {panic("plaintext is not a multiple of the block size")}

	block, err := aes.NewCipher(key)if err != nil {panic(err)}// IV需要独特,但不安全。 所以这很常见// 将其包括在密文的开头。
	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]if _, err := io.ReadFull(rand.Reader, iv); err != nil {panic(err)}

	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)// 记住密文必须经过认证是很重要的// (即通过使用crypto/hmac)以及为了加密而被加密// 保持secure。

	fmt.Printf("%x\n", ciphertext)}

type Stream

Stream表示流密码。

type Stream interface {        // XORKeyStream将给定片中的每个字节与来自该字节的一个字节异或        // 密码的密钥流。 Dst和src可能指向相同的内存。        // 如果len(dst)<len(src),XORKeyStream应该是恐慌的。 它是可以接受的        // 传递比src更大的dst,在那种情况下,XORKeyStream会        // 只更新dst[:len(src)]并且不会触及dst的其余部分。        XORKeyStream(dst, src []byte)}

func NewCFBDecrypter

func NewCFBDecrypter(block Block, iv []byte) Stream

新的 CFB 解密器使用给定的块返回一个使用密码反馈模式解密的 Stream。iv 的长度必须与块的块大小相同。

示例

package mainimport ("crypto/aes""crypto/cipher""encoding/hex""fmt")func main() {
	key := []byte("example key 1234")
	ciphertext, _ := hex.DecodeString("22277966616d9bc47177bd02603d08c9a67d5380d0fe8cf3b44438dff7b9")

	block, err := aes.NewCipher(key)if err != nil {panic(err)}// IV需要独特,但不安全。 所以这很常见// 将其包括在密文的开头。if len(ciphertext) < aes.BlockSize {panic("ciphertext too short")}
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	stream := cipher.NewCFBDecrypter(block, iv)// 如果两个参数相同,XORKeyStream可以在原地工作。
	stream.XORKeyStream(ciphertext, ciphertext)
	fmt.Printf("%s", ciphertext)}

func NewCFBEncrypter

func NewCFBEncrypter(block Block, iv []byte) Stream

NewCFBEncrypter 使用给定的 Block 返回一个使用密码反馈模式加密的 Stream。iv 的长度必须与块的块大小相同。

示例

package mainimport ("crypto/aes""crypto/cipher""crypto/rand""io")func main() {
	key := []byte("example key 1234")
	plaintext := []byte("some plaintext")

	block, err := aes.NewCipher(key)if err != nil {panic(err)}// IV需要独特,但不安全。 所以这很常见// 将其包括在密文的开头。
	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]if _, err := io.ReadFull(rand.Reader, iv); err != nil {panic(err)}

	stream := cipher.NewCFBEncrypter(block, iv)
	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)// 记住密文必须经过认证是很重要的// (即通过使用crypto/hmac)以及为了加密而被加密// 保持secure。}

func NewCTR

func NewCTR(block Block, iv []byte) Stream

NewCTR 返回一个 Stream,它使用计数器模式下的给定 Block加密/解密。iv 的长度必须与块的块大小相同。

示例

package mainimport ("crypto/aes""crypto/cipher""crypto/rand""fmt""io")func main() {
	key := []byte("example key 1234")
	plaintext := []byte("some plaintext")

	block, err := aes.NewCipher(key)if err != nil {panic(err)}// IV需要独特,但不安全。 所以这很常见// 将其包括在密文的开头。
	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]if _, err := io.ReadFull(rand.Reader, iv); err != nil {panic(err)}

	stream := cipher.NewCTR(block, iv)
	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)// 记住密文必须经过认证是很重要的// (即通过使用crypto/hmac)以及为了加密而被加密// 保持secure。// CTR模式对于加密和解密都是一样的,所以我们可以// 也用NewCTR解密该密文。
	plaintext2 := make([]byte, len(plaintext))
	stream = cipher.NewCTR(block, iv)
	stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])

	fmt.Printf("%s\n", plaintext2)}

func NewOFB

func NewOFB(b Block, iv []byte) Stream

NewOFB 返回一个在输出反馈模式下使用分组密码 b 进行加密或解密的 Stream。初始化矢量 iv 的长度必须等于 b 的块大小。

示例

package mainimport ("crypto/aes""crypto/cipher""crypto/rand""fmt""io")func main() {
	key := []byte("example key 1234")
	plaintext := []byte("some plaintext")

	block, err := aes.NewCipher(key)if err != nil {panic(err)}// IV需要独特,但不安全。 所以这很常见// 将其包括在密文的开头。
	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]if _, err := io.ReadFull(rand.Reader, iv); err != nil {panic(err)}

	stream := cipher.NewOFB(block, iv)
	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)// 记住密文必须经过认证是很重要的// (即通过使用crypto/hmac)以及为了加密而被加密// 保持secure。// OFB模式对加密和解密都是一样的,所以我们可以// 也使用 NewOFB 解密该密文。

	plaintext2 := make([]byte, len(plaintext))
	stream = cipher.NewOFB(block, iv)
	stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])

	fmt.Printf("%s\n", plaintext2)}

type StreamReader

StreamReader 将 Stream 封装到 io.Reader 中。它调用 XORKeyStream 来处理通过的每一片数据。

type StreamReader struct {
        S Stream
        R io.Reader}

示例

package mainimport ("crypto/aes""crypto/cipher""io""os")func main() {
	key := []byte("example key 1234")

	inFile, err := os.Open("encrypted-file")if err != nil {panic(err)}
	defer inFile.Close()

	block, err := aes.NewCipher(key)if err != nil {panic(err)}// 如果密钥对于每个密文都是唯一的,那么可以使用零// IV.var iv [aes.BlockSize]byte
	stream := cipher.NewOFB(block, iv[:])

	outFile, err := os.OpenFile("decrypted-file", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)if err != nil {panic(err)}
	defer outFile.Close()

	reader := &cipher.StreamReader{S: stream, R: inFile}// 将输入文件复制到输出文件,随着我们的解密。if _, err := io.Copy(outFile, reader); err != nil {panic(err)}// 请注意,这个例子是简单的,因为它省略了// 加密数据的认证。 如果你真的使用// StreamReader以这种方式,攻击者可以翻转任意位// 输出。}

func (StreamReader) Read

func (r StreamReader) Read(dst []byte) (n int, err error)

type StreamWriter

StreamWriter 将 Stream 封装到 io.Writer 中。它调用 XORKeyStream 来处理通过的每一片数据。如果任何写入调用返回短,那么 StreamWriter 不同步并且必须被丢弃。StreamWriter 没有内部缓冲;不需要调用 Close 来刷新写入数据。

type StreamWriter struct {
        S   Stream
        W   io.Writer
        Err error // unused}

示例

package mainimport ("crypto/aes""crypto/cipher""io""os")func main() {
	key := []byte("example key 1234")

	inFile, err := os.Open("plaintext-file")if err != nil {panic(err)}
	defer inFile.Close()

	block, err := aes.NewCipher(key)if err != nil {panic(err)}// 如果密钥对于每个密文都是唯一的,那么可以使用zero// IV.var iv [aes.BlockSize]byte
	stream := cipher.NewOFB(block, iv[:])

	outFile, err := os.OpenFile("encrypted-file", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)if err != nil {panic(err)}
	defer outFile.Close()

	writer := &cipher.StreamWriter{S: stream, W: outFile}// 将输入文件复制到输出文件,并随时加密。if _, err := io.Copy(writer, inFile); err != nil {panic(err)}// 请注意,这个例子是简单的,因为它省略了// 加密数据的认证。 如果你真的使用// StreamReader以这种方式,攻击者可以翻转任意位// 解密的结果。}

func (StreamWriter) Close

func (w StreamWriter) Close() error

Close 关闭底层 Writer 并返回其 Close 返回值,如果 Writer 也是 io.Closer。否则它返回零。

func (StreamWriter) Write

func (w StreamWriter) Write(src []byte) (n int, err error)
上一篇:下一篇: