Golang标准库——crypto(3)

DevilRoshan · · 746 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

  • tls

tls

tls包实现了TLS 1.2,细节参见RFC 5246

Constants

const (
    TLS_RSA_WITH_RC4_128_SHA                uint16 = 0x0005
    TLS_RSA_WITH_3DES_EDE_CBC_SHA           uint16 = 0x000a
    TLS_RSA_WITH_AES_128_CBC_SHA            uint16 = 0x002f
    TLS_RSA_WITH_AES_256_CBC_SHA            uint16 = 0x0035
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA        uint16 = 0xc007
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA    uint16 = 0xc009
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA    uint16 = 0xc00a
    TLS_ECDHE_RSA_WITH_RC4_128_SHA          uint16 = 0xc011
    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA     uint16 = 0xc012
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA      uint16 = 0xc013
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA      uint16 = 0xc014
    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   uint16 = 0xc02f
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
)

可选的加密组的ID的列表。参见:http://www.iana.org/assignments/tls-parameters/tls-parameters.xml

const (
    VersionSSL30 = 0x0300
    VersionTLS10 = 0x0301
    VersionTLS11 = 0x0302
    VersionTLS12 = 0x0303
)

type ClientAuthType

type ClientAuthType int

ClientAuthType类型声明服务端将遵循的TLS客户端验证策略。

const (
    NoClientCert ClientAuthType = iota
    RequestClientCert
    RequireAnyClientCert
    VerifyClientCertIfGiven
    RequireAndVerifyClientCert
)

type CurveID

type CurveID uint16

CurveID是TLS椭圆曲线的标识符的类型。

参见: http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8

const (
    CurveP256 CurveID = 23
    CurveP384 CurveID = 24
    CurveP521 CurveID = 25
)

type Certificate

type Certificate struct {
    Certificate [][]byte
    PrivateKey  crypto.PrivateKey // 只支持rsa.PrivateKey和*ecdsa.PrivateKey类型
    // OCSPStaple包含一个可选的OCSP staple的回复,当客户端要求时用于回复客户端
    OCSPStaple []byte
    // Leaf是解析后的叶证书,可以使用x509.ParseCertificate初始化,
    // 以简化每次TLS客户端进行客户端认证时握手的过程。如果Leaf是nil,叶证书会根据需要解析。
    Leaf *x509.Certificate
}

Certificate是一个或多个证书的链条,叶证书在最前面。

func LoadX509KeyPair

func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error)

LoadX509KeyPair读取并解析一对文件获取公钥和私钥。这些文件必须是PEM编码的。

func X509KeyPair

func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error)

X509KeyPair解析一对PEM编码的数据获取公钥和私钥。

type ClientSessionState

type ClientSessionState struct {
    sessionTicket      []uint8               // Encrypted ticket used for session resumption with server
    vers               uint16                // TLS version negotiated for the session
    cipherSuite        uint16                // Ciphersuite negotiated for the session
    masterSecret       []byte                // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret
    serverCertificates []*x509.Certificate   // Certificate chain presented by the server
    verifiedChains     [][]*x509.Certificate // Certificate chains we built for verification
    receivedAt         time.Time             // When the session ticket was received from the server
    ocspResponse       []byte                // Stapled OCSP response presented by the server
    scts               [][]byte              // SCTs presented by the server

    // TLS 1.3 fields.
    nonce  []byte    // Ticket nonce sent by the server, to derive PSK
    useBy  time.Time // Expiration of the ticket lifetime as set by the server
    ageAdd uint32    // Random obfuscation factor for sending the ticket age
}

ClientSessionState包含客户端所需的用于恢复TLS会话的状态。

type ClientSessionCache

type ClientSessionCache interface {
    // Get搜索与给出的键相关联的*ClientSessionState并用ok说明是否找到
    Get(sessionKey string) (session *ClientSessionState, ok bool)
    // Put将*ClientSessionState与给出的键关联并写入缓存中
    Put(sessionKey string, cs *ClientSessionState)
}

ClientSessionCache是ClientSessionState对象的缓存,可以被客户端用于恢复与某个服务端的TLS会话。本类型的实现期望被不同线程并行的调用。

func NewLRUClientSessionCache

func NewLRUClientSessionCache(capacity int) ClientSessionCache

函数使用给出的容量创建一个采用LRU策略的ClientSessionState,如果capacity<1会采用默认容量。

type Config

type Config struct {
    // Rand提供用于生成随机数和RSA盲签名的熵源,该接口必须能安全的用于并发。
    // 如果Rand是nil,会使用crypto/rand包的密码用随机数读取器。
    Rand io.Reader
    // Time返回当前时间,如果是nil会使用time.Now。
    Time func() time.Time
    // 不少于一个证书的链,用于提供给连接的另一端,服务端必须保证至少有一个证书。
    Certificates []Certificate
    // NameToCertificate映射证书名到证书。
    // 注意证书名可以是"*.example.com "的格式,因此证书名不是必须为域名。
    // 参见Config.BuildNameToCertificate方法。
    // 如本字段为nil,Certificates字段的第一个成员会被用于所有连接。
    NameToCertificate map[string]*Certificate
    // RootCAs定义权威根证书,客户端会在验证服务端证书时用到本字段。
    // 如果RootCAs是nil,TLS会使用主机的根CA池。
    RootCAs *x509.CertPool
    // 可以支持的应用层协议的列表
    NextProtos []string
    // 用于认证返回证书的主机名(除非设置了InsecureSkipVerify)。
    // 也被用在客户端的握手里,以支持虚拟主机。
    ServerName string
    // ClientAuth决定服务端的认证策略,默认是NoClientCert。
    ClientAuth ClientAuthType
    // ClientCAs定义权威根证书,服务端会在采用ClientAuth策略时使用它来认证客户端证书。
    ClientCAs *x509.CertPool
    // InsecureSkipVerify控制客户端是否认证服务端的证书链和主机名。
    // 如果InsecureSkipVerify为真,TLS连接会接受服务端提供的任何证书和该证书中的任何主机名。
    // 此时,TLS连接容易遭受中间人攻击,这种设置只应用于测试。
    InsecureSkipVerify bool
    // CipherSuites是支持的加密组合列表。如果CipherSuites为nil,
    // TLS连接会使用本包的实现支持的密码组合列表。
    CipherSuites []uint16
    // 本字段控制服务端是选择客户端最期望的密码组合还是服务端最期望的密码组合。
    // 如果本字段为真,服务端会优先选择CipherSuites字段中靠前的密码组合使用。
    PreferServerCipherSuites bool
    // SessionTicketsDisabled可以设为假以关闭会话恢复支持。
    SessionTicketsDisabled bool
    // SessionTicketKey被TLS服务端用于提供哦你会话恢复服务,参见RFC 5077。
    // 如果本字段为零值,它会在第一次服务端握手之前填写上随机数据。
    //
    // 如果多个服务端都在终止和同一主机的连接,它们应拥有相同的SessionTicketKey。
    // 如果SessionTicketKey泄露了,使用该键的之前的记录和未来的TLS连接可能会被盗用。
    SessionTicketKey [32]byte
    // SessionCache是ClientSessionState的缓存,用于恢复TLS会话。
    ClientSessionCache ClientSessionCache
    // MinVersion包含可接受的最低SSL/TLS版本。如果为0,会将SSLv3作为最低版本。
    MinVersion uint16
    // MaxVersion包含可接受的最高SSL/TLS版本。
    // 如果为0,会将本包使用的版本作为最高版本,目前是TLS 1.2。
    MaxVersion uint16
    // 本字段包含用于ECDHE握手的椭圆曲线的ID,按优先度排序。如为空,会使用默认值。
    CurvePreferences []CurveID
    // 内含隐藏或非导出字段
}

Config结构类型用于配置TLS客户端或服务端。在本类型的值提供给TLS函数后,就不应再修改该值。Config类型值可能被重用;tls包也不会修改它。

func (*Config) BuildNameToCertificate

func (c *Config) BuildNameToCertificate()

BuildNameToCertificate解析c.Certificates并将每一个叶证书的CommonName和SubjectAlternateName字段用于创建c.NameToCertificate。

type ConnectionState

type ConnectionState struct {
    Version                    uint16                // 连接使用的TLS版本
    HandshakeComplete          bool                  // TLS握手是否完成
    DidResume                  bool                  // 连接恢复了之前的TLS连接
    CipherSuite                uint16                // 使用的加密程序组合
    NegotiatedProtocol         string                // 商定的下一层协议
    NegotiatedProtocolIsMutual bool                  // 商定的协议是服务端建议的
    ServerName                 string                // 服务端名(仅服务端有)
    PeerCertificates           []*x509.Certificate   // 远端提供的证书链
    VerifiedChains             [][]*x509.Certificate // 从PeerCertificates建立的认证链
}

ConnectionState类型记录连接的基本TLS细节。

type Conn

type Conn struct {
    // constant
    conn        net.Conn
    isClient    bool
    handshakeFn func() error // (*Conn).clientHandshake or serverHandshake

    // handshakeStatus is 1 if the connection is currently transferring
    // application data (i.e. is not currently processing a handshake).
    // This field is only to be accessed with sync/atomic.
    handshakeStatus uint32
    // constant after handshake; protected by handshakeMutex
    handshakeMutex sync.Mutex
    handshakeErr   error   // error resulting from handshake
    vers           uint16  // TLS version
    haveVers       bool    // version has been negotiated
    config         *Config // configuration passed to constructor
    // handshakes counts the number of handshakes performed on the
    // connection so far. If renegotiation is disabled then this is either
    // zero or one.
    handshakes       int
    didResume        bool // whether this connection was a session resumption
    cipherSuite      uint16
    ocspResponse     []byte   // stapled OCSP response
    scts             [][]byte // signed certificate timestamps from server
    peerCertificates []*x509.Certificate
    // verifiedChains contains the certificate chains that we built, as
    // opposed to the ones presented by the server.
    verifiedChains [][]*x509.Certificate
    // serverName contains the server name indicated by the client, if any.
    serverName string
    // secureRenegotiation is true if the server echoed the secure
    // renegotiation extension. (This is meaningless as a server because
    // renegotiation is not supported in that case.)
    secureRenegotiation bool
    // ekm is a closure for exporting keying material.
    ekm func(label string, context []byte, length int) ([]byte, error)
    // resumptionSecret is the resumption_master_secret for handling
    // NewSessionTicket messages. nil if config.SessionTicketsDisabled.
    resumptionSecret []byte

    // ticketKeys is the set of active session ticket keys for this
    // connection. The first one is used to encrypt new tickets and
    // all are tried to decrypt tickets.
    ticketKeys []ticketKey

    // clientFinishedIsFirst is true if the client sent the first Finished
    // message during the most recent handshake. This is recorded because
    // the first transmitted Finished message is the tls-unique
    // channel-binding value.
    clientFinishedIsFirst bool

    // closeNotifyErr is any error from sending the alertCloseNotify record.
    closeNotifyErr error
    // closeNotifySent is true if the Conn attempted to send an
    // alertCloseNotify record.
    closeNotifySent bool

    // clientFinished and serverFinished contain the Finished message sent
    // by the client or server in the most recent handshake. This is
    // retained to support the renegotiation extension and tls-unique
    // channel-binding.
    clientFinished [12]byte
    serverFinished [12]byte

    clientProtocol         string
    clientProtocolFallback bool

    // input/output
    in, out   halfConn
    rawInput  bytes.Buffer // raw input, starting with a record header
    input     bytes.Reader // application data waiting to be read, from rawInput.Next
    hand      bytes.Buffer // handshake data waiting to be read
    outBuf    []byte       // scratch buffer used by out.encrypt
    buffering bool         // whether records are buffered in sendBuf
    sendBuf   []byte       // a buffer of records waiting to be sent

    // bytesSent counts the bytes of application data sent.
    // packetsSent counts packets.
    bytesSent   int64
    packetsSent int64

    // retryCount counts the number of consecutive non-advancing records
    // received by Conn.readRecord. That is, records that neither advance the
    // handshake, nor deliver application data. Protected by in.Mutex.
    retryCount int

    // activeCall is an atomic int32; the low bit is whether Close has
    // been called. the rest of the bits are the number of goroutines
    // in Conn.Write.
    activeCall int32

    tmp [16]byte
}

Conn代表一个安全连接。本类型实现了net.Conn接口。

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

LocalAddr返回本地网络地址。

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

LocalAddr返回远端网络地址。

func (*Conn) ConnectionState

func (c *Conn) ConnectionState() ConnectionState

ConnectionState返回该连接的基本TLS细节。

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline设置该连接的读写操作绝对期限。t为Time零值表示不设置超时。在一次Write/Read方法超时后,TLS连接状态会被破坏,之后所有的读写操作都会返回同一错误。

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline设置该连接的读操作绝对期限。t为Time零值表示不设置超时。

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

SetReadDeadline设置该连接的写操作绝对期限。t为Time零值表示不设置超时。在一次Write方法超时后,TLS连接状态会被破坏,之后所有的写操作都会返回同一错误。

func (*Conn) Handshake

func (c *Conn) Handshake() error

Handshake执行客户端或服务端的握手协议(如果还没有执行的话)。本包的大多数应用不需要显式的调用Handsake方法:第一次Read或Write方法会自动调用本方法。

func (*Conn) VerifyHostname

func (c *Conn) VerifyHostname(host string) error

VerifyHostname检查用于连接到host的对等实体证书链是否合法。如果合法,它会返回nil;否则,会返回一个描述该问题的错误。

func (*Conn) OCSPResponse

func (c *Conn) OCSPResponse() []byte

OCSPResponse返回来自服务端的OCSP staple回复(如果有)。只有客户端可以使用本方法。

func (*Conn) Read

func (c *Conn) Read(b []byte) (n int, err error)

Read从连接读取数据,可设置超时,参见SetDeadline和SetReadDeadline。

func (*Conn) Write

func (c *Conn) Write(b []byte) (int, error)

Write将数据写入连接,可设置超时,参见SetDeadline和SetWriteDeadline。

func (*Conn) Close

func (c *Conn) Close() error

Close关闭连接。

func Client

func Client(conn net.Conn, config *Config) *Conn

Client使用conn作为下层传输接口返回一个TLS连接的客户端侧。配置参数config必须是非nil的且必须设置了ServerName或者InsecureSkipVerify字段。

func Server

func Server(conn net.Conn, config *Config) *Conn

Server使用conn作为下层传输接口返回一个TLS连接的服务端侧。配置参数config必须是非nil的且必须含有至少一个证书。

func Dial

func Dial(network, addr string, config *Config) (*Conn, error)

Dial使用net.Dial连接指定的网络和地址,然后发起TLS握手,返回生成的TLS连接。Dial会将nil的配置视为零值的配置;参见Config类型的文档获取细节。

func DialWithDialer

func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error)

DialWithDialer使用dialer.Dial连接指定的网络和地址,然后发起TLS握手,返回生成的TLS连接。dialer中的超时和期限设置会将连接和TLS握手作为一个整体来应用。

DialWithDialer会将nil的配置视为零值的配置;参见Config类型的文档获取细节。

func Listen

func Listen(network, laddr string, config *Config) (net.Listener, error)

函数创建一个TLS监听器,使用net.Listen函数接收给定地址上的连接。配置参数config必须是非nil的且必须含有至少一个证书。

func NewListener

func NewListener(inner net.Listener, config *Config) net.Listener

函数创建一个TLS监听器,该监听器接受inner接收到的每一个连接,并调用Server函数包装这些连接。配置参数config必须是非nil的且必须含有至少一个证书。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:DevilRoshan

查看原文:Golang标准库——crypto(3)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

746 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传