# package cipher
`import "crypto/cipher"`
cipher包实现了多个标准的用于包装底层块加密算法的加密算法实现。
参见[http://csrc.nist.gov/groups/ST/toolkit/BCM/current_modes.html](http://csrc.nist.gov/groups/ST/toolkit/BCM/current_modes.html)和NIST Special Publication 800-38A。
## Index
* [type Block](#Block)
* [type BlockMode](#BlockMode)
* [func NewCBCDecrypter(b Block, iv []byte) BlockMode](#NewCBCDecrypter)
* [func NewCBCEncrypter(b Block, iv []byte) BlockMode](#NewCBCEncrypter)
* [type Stream](#Stream)
* [func NewCFBDecrypter(block Block, iv []byte) Stream](#NewCFBDecrypter)
* [func NewCFBEncrypter(block Block, iv []byte) Stream](#NewCFBEncrypter)
* [func NewCTR(block Block, iv []byte) Stream](#NewCTR)
* [func NewOFB(b Block, iv []byte) Stream](#NewOFB)
* [type StreamReader](#StreamReader)
* [func (r StreamReader) Read(dst []byte) (n int, err error)](#StreamReader.Read)
* [type StreamWriter](#StreamWriter)
* [func (w StreamWriter) Write(src []byte) (n int, err error)](#StreamWriter.Write)
* [func (w StreamWriter) Close() error](#StreamWriter.Close)
* [type AEAD](#AEAD)
* [func NewGCM(cipher Block) (AEAD, error)](#NewGCM)
### Examples
* [NewCBCDecrypter](#example-NewCBCDecrypter)
* [NewCBCEncrypter](#example-NewCBCEncrypter)
* [NewCFBDecrypter](#example-NewCFBDecrypter)
* [NewCFBEncrypter](#example-NewCFBEncrypter)
* [NewCTR](#example-NewCTR)
* [NewOFB](#example-NewOFB)
* [StreamReader](#example-StreamReader)
* [StreamWriter](#example-StreamWriter)
## type [Block](https://github.com/golang/go/blob/master/src/crypto/cipher/cipher.go#L15 "View Source")
```
type Block interface {
// 返回加密字节块的大小
BlockSize() int
// 加密src的第一块数据并写入dst,src和dst可指向同一内存地址
Encrypt(dst, src []byte)
// 解密src的第一块数据并写入dst,src和dst可指向同一内存地址
Decrypt(dst, src []byte)
}
```
Block接口代表一个使用特定密钥的底层块加/解密器。它提供了加密和解密独立数据块的能力。
## type [BlockMode](https://github.com/golang/go/blob/master/src/crypto/cipher/cipher.go#L37 "View Source")
```
type BlockMode interface {
// 返回加密字节块的大小
BlockSize() int
// 加密或解密连续的数据块,src的尺寸必须是块大小的整数倍,src和dst可指向同一内存地址
CryptBlocks(dst, src []byte)
}
```
BlockMode接口代表一个工作在块模式(如CBC、ECB等)的加/解密器。
### func [NewCBCEncrypter](https://github.com/golang/go/blob/master/src/crypto/cipher/cbc.go#L35 "View Source")
```
func NewCBCEncrypter(b Block, iv []byte) BlockMode
```
返回一个密码分组链接模式的、底层用b加密的BlockMode接口,初始向量iv的长度必须等于b的块尺寸。
Example
```
key := []byte("example key 1234")
plaintext := []byte("exampleplaintext")
// CBC mode works on blocks so plaintexts may need to be padded to the
// next whole block. For an example of such padding, see
// https://tools.ietf.org/html/rfc5246#section-6.2.3.2\. Here we'll
// assume that the plaintext is already of the correct length.
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)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
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)
// It's important to remember that ciphertexts must be authenticated
// (i.e. by using crypto/hmac) as well as being encrypted in order to
// be secure.
fmt.Printf("%x\n", ciphertext)
```
### func [NewCBCDecrypter](https://github.com/golang/go/blob/master/src/crypto/cipher/cbc.go#L81 "View Source")
```
func NewCBCDecrypter(b Block, iv []byte) BlockMode
```
返回一个密码分组链接模式的、底层用b解密的BlockMode接口,初始向量iv必须和加密时使用的iv相同。
Example
```
key := []byte("example key 1234")
ciphertext, _ := hex.DecodeString("f363f3ccdcb12bb883abf484ba77d9cd7d32b5baecb3d4b1b3e0e4beffdb3ded")
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
if len(ciphertext) < aes.BlockSize {
panic("ciphertext too short")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
// CBC mode always works in whole blocks.
if len(ciphertext)%aes.BlockSize != 0 {
panic("ciphertext is not a multiple of the block size")
}
mode := cipher.NewCBCDecrypter(block, iv)
// CryptBlocks can work in-place if the two arguments are the same.
mode.CryptBlocks(ciphertext, ciphertext)
// If the original plaintext lengths are not a multiple of the block
// size, padding would have to be added when encrypting, which would be
// removed at this point. For an example, see
// https://tools.ietf.org/html/rfc5246#section-6.2.3.2\. However, it's
// critical to note that ciphertexts must be authenticated (i.e. by
// using crypto/hmac) before being decrypted in order to avoid creating
// a padding oracle.
fmt.Printf("%s\n", ciphertext)
```
Output:
```
exampleplaintext
```
## type [Stream](https://github.com/golang/go/blob/master/src/crypto/cipher/cipher.go#L29 "View Source")
```
type Stream interface {
// 从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
XORKeyStream(dst, src []byte)
}
```
Stream接口代表一个流模式的加/解密器。
### func [NewCFBEncrypter](https://github.com/golang/go/blob/master/src/crypto/cipher/cfb.go#L45 "View Source")
```
func NewCFBEncrypter(block Block, iv []byte) Stream
```
返回一个密码反馈模式的、底层用block加密的Stream接口,初始向量iv的长度必须等于block的块尺寸。
Example
```
key := []byte("example key 1234")
plaintext := []byte("some plaintext")
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
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)
// It's important to remember that ciphertexts must be authenticated
// (i.e. by using crypto/hmac) as well as being encrypted in order to
// be secure.
```
### func [NewCFBDecrypter](https://github.com/golang/go/blob/master/src/crypto/cipher/cfb.go#L52 "View Source")
```
func NewCFBDecrypter(block Block, iv []byte) Stream
```
返回一个密码反馈模式的、底层用block解密的Stream接口,初始向量iv必须和加密时使用的iv相同。
Example
```
key := []byte("example key 1234")
ciphertext, _ := hex.DecodeString("22277966616d9bc47177bd02603d08c9a67d5380d0fe8cf3b44438dff7b9")
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
if len(ciphertext) < aes.BlockSize {
panic("ciphertext too short")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
// XORKeyStream can work in-place if the two arguments are the same.
stream.XORKeyStream(ciphertext, ciphertext)
fmt.Printf("%s", ciphertext)
```
Output:
```
some plaintext
```
### func [NewOFB](https://github.com/golang/go/blob/master/src/crypto/cipher/ofb.go#L19 "View Source")
```
func NewOFB(b Block, iv []byte) Stream
```
返回一个输出反馈模式的、底层采用b生成key流的Stream接口,初始向量iv的长度必须等于b的块尺寸。
Example
```
key := []byte("example key 1234")
plaintext := []byte("some plaintext")
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
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)
// It's important to remember that ciphertexts must be authenticated
// (i.e. by using crypto/hmac) as well as being encrypted in order to
// be secure.
// OFB mode is the same for both encryption and decryption, so we can
// also decrypt that ciphertext with NewOFB.
plaintext2 := make([]byte, len(plaintext))
stream = cipher.NewOFB(block, iv)
stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])
fmt.Printf("%s\n", plaintext2)
```
Output:
```
some plaintext
```
### func [NewCTR](https://github.com/golang/go/blob/master/src/crypto/cipher/ctr.go#L26 "View Source")
```
func NewCTR(block Block, iv []byte) Stream
```
返回一个计数器模式的、底层采用block生成key流的Stream接口,初始向量iv的长度必须等于block的块尺寸。
Example
```
key := []byte("example key 1234")
plaintext := []byte("some plaintext")
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
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)
// It's important to remember that ciphertexts must be authenticated
// (i.e. by using crypto/hmac) as well as being encrypted in order to
// be secure.
// CTR mode is the same for both encryption and decryption, so we can
// also decrypt that ciphertext with NewCTR.
plaintext2 := make([]byte, len(plaintext))
stream = cipher.NewCTR(block, iv)
stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])
fmt.Printf("%s\n", plaintext2)
```
Output:
```
some plaintext
```
## type [StreamReader](https://github.com/golang/go/blob/master/src/crypto/cipher/io.go#L14 "View Source")
```
type StreamReader struct {
S Stream
R io.Reader
}
```
将一个Stream与一个io.Reader接口关联起来,Read方法会调用XORKeyStream方法来处理获取的所有切片。
Example
```
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)
}
// If the key is unique for each ciphertext, then it's ok to use a zero
// 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}
// Copy the input file to the output file, decrypting as we go.
if _, err := io.Copy(outFile, reader); err != nil {
panic(err)
}
// Note that this example is simplistic in that it omits any
// authentication of the encrypted data. It you were actually to use
// StreamReader in this manner, an attacker could flip arbitrary bits in
// the output.
```
### func (StreamReader) [Read](https://github.com/golang/go/blob/master/src/crypto/cipher/io.go#L19 "View Source")
```
func (r StreamReader) Read(dst []byte) (n int, err error)
```
## type [StreamWriter](https://github.com/golang/go/blob/master/src/crypto/cipher/io.go#L30 "View Source")
```
type StreamWriter struct {
S Stream
W io.Writer
Err error // unused
}
```
将一个Stream与一个io.Writer接口关联起来,Write方法会调用XORKeyStream方法来处理提供的所有切片。如果Write方法返回的n小于提供的切片的长度,则表示StreamWriter不同步,必须丢弃。StreamWriter没有内建的缓存,不需要调用Close方法去清空缓存。
Example
```
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)
}
// If the key is unique for each ciphertext, then it's ok to use a 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}
// Copy the input file to the output file, encrypting as we go.
if _, err := io.Copy(writer, inFile); err != nil {
panic(err)
}
// Note that this example is simplistic in that it omits any
// authentication of the encrypted data. It you were actually to use
// StreamReader in this manner, an attacker could flip arbitrary bits in
// the decrypted result.
```
### func (StreamWriter) [Write](https://github.com/golang/go/blob/master/src/crypto/cipher/io.go#L36 "View Source")
```
func (w StreamWriter) Write(src []byte) (n int, err error)
```
### func (StreamWriter) [Close](https://github.com/golang/go/blob/master/src/crypto/cipher/io.go#L50 "View Source")
```
func (w StreamWriter) Close() error
```
如果w.W字段实现了io.Closer接口,本方法会调用其Close方法并返回该方法的返回值;否则不做操作返回nil。
## type [AEAD](https://github.com/golang/go/blob/master/src/crypto/cipher/gcm.go#L14 "View Source")
```
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](https://github.com/golang/go/blob/master/src/crypto/cipher/gcm.go#L62 "View Source")
```
func NewGCM(cipher Block) (AEAD, error)
```
函数用迦洛瓦计数器模式包装提供的128位Block接口,并返回AEAD接口。
- 库
- package achive
- package tar
- package zip
- package bufio
- package builtin
- package bytes
- package compress
- package bzip2
- package flate
- package gzip
- package lzw
- package zlib
- package container
- package heap
- package list
- package ring
- package crypto
- package aes
- package cipher
- package des
- package dsa
- package ecdsa
- package elliptic
- package hmac
- package md5
- package rand
- package rc4
- package rsa
- package sha1
- package sha256
- package sha512
- package subtle
- package tls
- package x509
- package pkix
- package database
- package sql
- package driver
- package encoding
- package ascii85
- package asn1
- package base32
- package base64
- package binary
- package csv
- package gob
- package hex
- package json
- package pem
- package xml
- package errors
- package expvar
- package flag
- package fmt
- package go
- package doc
- package format
- package parser
- package printer
- package hash
- package adler32
- package crc32
- package crc64
- package fnv
- package html
- package template
- package image
- package color
- package palette
- package draw
- package gif
- package jpeg
- package png
- package index
- package suffixarray
- package io
- package ioutil
- package log
- package syslog
- package math
- package big
- package cmplx
- package rand
- package mime
- package multipart
- package net
- package http
- package cgi
- package cookiejar
- package fcgi
- package httptest
- package httputil
- package pprof
- package mail
- package rpc
- package jsonrpc
- package smtp
- package textproto
- package url
- package os
- package exec
- package signal
- package user
- package path
- package filepath
- package reflect
- package regexp
- package runtime
- package cgo
- package debug
- package pprof
- package race
- package sort
- package strconv
- package strings
- package sync
- package atomic
- package text
- package scanner
- package tabwriter
- package template
- package time
- package unicode
- package utf16
- package utf8
- package unsafe