非常教程

Go参考手册

加密 | crypto

crypto/tls

  • import "crypto/tls"
  • 概述
  • 索引
  • 示例

概述

按照RFC 5246 的规定,软件包部分实现了 TLS 1.2。

索引

  • Constants
  • func Listen(network, laddr string, config *Config) (net.Listener, error)
  • func NewListener(inner net.Listener, config *Config) net.Listener
  • type Certificate
  • func LoadX509KeyPair(certFile, keyFile string) (Certificate, error)
  • func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error)
  • type CertificateRequestInfo
  • type ClientAuthType
  • type ClientHelloInfo
  • type ClientSessionCache
  • func NewLRUClientSessionCache(capacity int) ClientSessionCache
  • type ClientSessionState
  • type Config
  • func (c *Config) BuildNameToCertificate()
  • func (c *Config) Clone() *Config
  • func (c *Config) SetSessionTicketKeys(keys [][32]byte)
  • type Conn
  • func Client(conn net.Conn, config *Config) *Conn
  • func Dial(network, addr string, config *Config) (*Conn, error)
  • func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error)
  • func Server(conn net.Conn, config *Config) *Conn
  • func (c *Conn) Close() error
  • func (c *Conn) CloseWrite() error
  • func (c *Conn) ConnectionState() ConnectionState
  • func (c *Conn) Handshake() error
  • func (c *Conn) LocalAddr() net.Addr
  • func (c *Conn) OCSPResponse() []byte
  • func (c *Conn) Read(b []byte) (n int, err error)
  • func (c *Conn) RemoteAddr() net.Addr
  • func (c *Conn) SetDeadline(t time.Time) error
  • func (c *Conn) SetReadDeadline(t time.Time) error
  • func (c *Conn) SetWriteDeadline(t time.Time) error
  • func (c *Conn) VerifyHostname(host string) error
  • func (c *Conn) Write(b []byte) (int, error)
  • type ConnectionState
  • type CurveID
  • type RecordHeaderError
  • func (e RecordHeaderError) Error() string
  • type RenegotiationSupport
  • type SignatureScheme
  • Bugs

示例

Config (KeyLogWriter) Dial

文件包

alert.go cipher_suites.go common.go conn.go handshake_client.go handshake_messages.go handshake_server.go key_agreement.go prf.go ticket.go tls.go

常量

此软件包已实施或已经实施的密码套件 ID 列表。

取自http://www.iana.org/assignments/tls-parameters/tls-parameters.xml

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_RSA_WITH_AES_128_CBC_SHA256         uint16 = 0x003c
        TLS_RSA_WITH_AES_128_GCM_SHA256         uint16 = 0x009c
        TLS_RSA_WITH_AES_256_GCM_SHA384         uint16 = 0x009d
        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_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
        TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256   uint16 = 0xc027
        TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   uint16 = 0xc02f
        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   uint16 = 0xc030
        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
        TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305    uint16 = 0xcca8
        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305  uint16 = 0xcca9

        // TLS_FALLBACK_SCSV不是标准密码套件,而是指标
        // 客户端正在进行版本回退。 参见
        // https://tools.ietf.org/html/rfc7507。
        TLS_FALLBACK_SCSV uint16 = 0x5600
)
const (
        VersionSSL30 = 0x0300
        VersionTLS10 = 0x0301
        VersionTLS11 = 0x0302
        VersionTLS12 = 0x0303
)

func Listen(查看源代码)

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

Listen 会使用 net.Listen 创建一个 TLS 侦听器来接受给定网络地址上的连接。配置配置必须非零,并且必须包含至少一个证书或者设置 GetCertificate。

func NewListener(查看源代码)

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

NewListener创建一个 Listener,它接受来自内部 Listener 的连接并将每个连接包装在 Server 中。配置必须非零,并且必须包含至少一个证书或者设置 GetCertificate。

type Certificate(查看源代码)

证书是一个或多个证书的链,首先是 leaf。

type Certificate struct {
        Certificate [][]byte
        // PrivateKey包含与公钥对应的私钥
        // 在Leaf中。 对于服务器,这必须实现
        // crypto.Decrypter,带有RSA或ECDSA 
        // (执行客户端身份验证),这必须是
        // 使用RSA或ECDSA PublicKey。
        PrivateKey crypto.PrivateKey
        // OCSPStaple包含一个可选的OCSP响应
        // 给要求它的客户端。
        OCSPStaple []byte
        // SignedCertificateTimestamps包含一个可选的Signed列表
        // 证书时间戳将提供给请求它的客户端。
        SignedCertificateTimestamps [][]byte
        // Leaf是叶证书的解析形式,可能是
        // 使用x509.ParseCertificate初始化以减少per-handshaking(每次握手)
        // 处理进行客户端身份验证的TLS客户端。 如果没有,那么
        // leaf证书将根据需要进行解析。
        Leaf *x509.Certificate
}

func LoadX509KeyPair(查看源代码)

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

LoadX509KeyPair 读取并解析来自一对文件的公钥/私钥对。这些文件必须包含 PEM 编码数据。证书文件可能包含 leaf 证书之后的中间证书以形成证书链。成功返回时,Certificate.Leaf 将为零,因为不会保留解析的证书形式。

func X509KeyPair(查看源代码)

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

X509KeyPair 从一对 PEM 编码数据中解析公钥/私钥对。成功返回时,Certificate.Leaf 将为零,因为不会保留解析的证书形式。

type CertificateRequestInfo(查看源代码)

CertificateRequestInfo 包含来自服务器的 CertificateRequest 消息的信息,该消息用于请求客户端的证书和控制证明。

type CertificateRequestInfo struct {
        // AcceptableCAs包含零个或多个DER编码的X.501
        // 杰出的名称(Names)。 这些是根CA或中间CA的名称
        // 服务器希望返回的证书由签名。 一个
        // 空切片表示服务器没有首选项。
        AcceptableCAs [][]byte

        // SignatureSchemes列出了服务器的签名方案
        // 愿意核实。
        SignatureSchemes []SignatureScheme
}

type ClientAuthType(查看源代码)

ClientAuthType 声明服务器将遵循 TLS 客户端身份验证的策略。

type ClientAuthType int
const (
        NoClientCert ClientAuthType = iota
        RequestClientCert
        RequireAnyClientCert
        VerifyClientCertIfGiven
        RequireAndVerifyClientCert
)

type ClientHelloInfo(查看源代码)

ClientHelloInfo 包含来自 ClientHello 消息的信息,以指导 GetCertificate 回调中的证书选择。

type ClientHelloInfo struct {
        // CipherSuites列出了客户端支持的CipherSuite(例如
        // TLS_RSA_WITH_RC4_128_SHA)。
        CipherSuites []uint16

        // ServerName表示客户端请求的服务器的名称
        // 为了支持虚拟主机。 ServerName仅在设置时设置
        // 客户端正在使用SNI(参见
        // http://tools.ietf.org/html/rfc4366#section-3.1)。
        ServerName string

        // SupportedCurves列出客户端支持的椭圆曲线。
        // 仅当支持的椭圆曲线时,才设置SupportedCurves
        // 正在使用扩展(参见
        // http://tools.ietf.org/html/rfc4492#section-5.1.1)。
        SupportedCurves []CurveID

        // SupportedPoints列出了客户端支持的点格式。
        // 仅当支持的点格式扩展时才设置SupportedPoints
        // 正在使用(参见
        // http://tools.ietf.org/html/rfc4492#section-5.1.2)。
        SupportedPoints []uint8

        // SignatureSchemes列出了客户端的签名和哈希方案
        // 愿意验证。 SignatureSchemes仅在签名时设置
        // 正在使用算法扩展(参见
        // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1)。
        SignatureSchemes []SignatureScheme

        // SupportedProtos列出客户端支持的应用程序协议。
        // 仅在应用程序层协议时设置SupportedProtos
        // 正在使用谈判扩展(参见
        // https://tools.ietf.org/html/rfc7301#section-3.1)。
        //
        // 服务器可以通过在以下设置Config.NextProtos来选择协议
        // GetConfigForClient返回值。
        SupportedProtos []string

        // SupportedVersions列出客户端支持的TLS版本。
        // 对于小于1.3的TLS版本,这是从最大值推断出来的
        // 客户端广告的版本,所以除最大值之外的其他值
        // 如果使用可能会被拒绝。
        SupportedVersions []uint16

        // Conn是连接的基础net.Conn。 匆读
        // 来自或写入此连接; 这将导致TLS
        // 连接失败。
        Conn net.Conn
}

type ClientSessionCache(查看源代码)

ClientSessionCache 是​​ ClientSessionState 对象的缓存,可由客户端用来恢复与给定服务器的 TLS 会话。ClientSessionCache 实现应该期望从不同的 goroutine 同时调用。只支持基于票据的恢复,不支持基于 SessionID 的恢复。

type ClientSessionCache interface {
        // 获取与给定密钥关联的ClientSessionState的搜索。
        // 返回时,如果找到一个,则确定。
        Get(sessionKey string) (session *ClientSessionState, ok bool)

        // Put使用给定键将ClientSessionState添加到缓存中。
        Put(sessionKey string, cs *ClientSessionState)
}

func NewLRUClientSessionCache(查看源代码)

func NewLRUClientSessionCache(capacity int) ClientSessionCache

NewLRUClientSessionCache 返回一个具有使用 LRU 策略的给定容量的 ClientSessionCache。如果容量<1,则使用默认容量。

type ClientSessionState(查看源代码)

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

type ClientSessionState struct {
        // 包含已过滤或未导出的字段
}

type Config(查看源代码)

配置结构用于配置 TLS 客户端或服务器。在传递给 TLS 函数之后,它不能被修改。配置可能会被重用; tls 包也不会修改。

type Config struct {
        // Rand为nonce和RSA致盲提供了熵的来源。
        // 如果Rand为零,则TLS在包中使用加密随机读取器
        // crypto/rand。
        // 阅读器必须安全使用多个goroutines。
        Rand io.Reader

        // 时间将当前时间作为自纪元以来的秒数返回。
        // 如果Time为nil,则TLS使用time.Now。
        Time func() time.Time

        // 证书包含一个或多个要呈现的证书链
        // 连接的另一面。 服务器配置必须包含
        // 至少一个证书或设置GetCertificate。 客户端正在
        // 客户端身份验证可以设置证书或
        // GetClientCertificate。
        Certificates []Certificate

        // NameToCertificate从证书名称映射到元素
        // 证书。 请注意,证书名称可以是表单
        // '* .example.com'因此不必是域名。
        // 请参见Config.BuildNameToCertificate
        // nil值导致使用证书的第一个元素
        // 对于所有连接。
        NameToCertificate map[string]*Certificate

        // GetCertificate根据给定的值返回证书
        // ClientHelloInfo。 只有在客户提供SNI时才会调用
        // 信息或证书是否为空。
        //
        // 如果GetCertificate为nil或返回nil,则证书为
        // 从NameToCertificate检索。 如果NameToCertificate是nil,那么
        // 将使用证书的第一个元素。
        GetCertificate func(*ClientHelloInfo) (*Certificate, error)

        // GetClientCertificate,如果不是nil,则在服务器请求时调用
        // 来自客户的证书。 如果设置,证书的内容将
        // 被忽略。
        //
        // 如果GetClientCertificate返回错误,则握手(handshake)将是
        // 中止,将返回该错误。 除此以外
        // GetClientCertificate必须返回非零证书。 如果
        // Certificate.Certificate为空,则不会发送任何证书
        // 服务器。 如果这对服务器来说是不可接受的,那么它可能会中止
        // 握手。
        //
        // 可以多次调用GetClientCertificate
        // 如果发生重新协商或者正在使用TLS 1.3,则连接。
        GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)

        // GetConfigForClient,如果不是nil,则在ClientHello之后调用
        // 从客户端那里收到 它可能会返回一个非零配置
        // 更改将用于处理此连接的Config。 如果
        // 返回的Config为nil,将使用原始配置。该
        // 此回调返回的配置可能不会随后被修改。
        //
        // 如果GetConfigForClient为nil,则传递给Server()的Config将为
        // 用于所有连接。
        //
        // 对于返回的Config中的字段,会话票证密钥是唯一的
        // 如果未设置,将从原始配置中复制。
        // 具体来说,如果在原始上调用了SetSessionTicketKeys
        // 配置但不在返回的配置上,然后从票证键
        // 原始配置将在使用前复制到新配置中。
        // 否则,如果在原始配置中设置了SessionTicketKey但是
        // 不在返回的配置中然后它将被复制到返回的
        // 使用前配置。 如果这两种情况都不适用那么关键
        // 返回的配置中的材料将用于会话票证。
        GetConfigForClient func(*ClientHelloInfo) (*Config, error)

        // VerifyPeerCertificate,如果不是nil,则在正常情况下被调用
        // 由TLS客户端或服务器验证证书。 它
        // 接收对等方提供的原始ASN.1证书
        // 正常处理发现的任何经过验证的链。 如果它返回一个
        // 非零错误,中止握手并产生错误。
        //
        // 如果正常验证失败,那么握手将在之前中止
        // 考虑这个回调。 如果禁用正常验证
        // 设置InsecureSkipVerify然后会考虑这个回调但是
        // verifiedChains参数将始终为零。
        VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error

        // RootCAs定义了根证书授权的集合
        // 客户端在验证服务器证书时使用。
        // 如果RootCAs为nil,则TLS使用主机的根CA集。
        RootCAs *x509.CertPool

        // NextProtos是受支持的应用程序级协议列表。
        NextProtos []string

        // ServerName用于验证返回的主机名
        // 证书,除非给出InsecureSkipVerify。 它也包括在内
        // 在客户端的握手中支持虚拟主机,除非它是
        // 一个IP地址。
        ServerName string

        // ClientAuth确定服务器的策略
        // TLS客户端身份验证。 默认值为NoClientCert。
        ClientAuth ClientAuthType

        // ClientCAs定义了根证书颁发机构的集合
        // 服务器使用,如果需要验证客户端证书
        // 通过ClientAuth中的策略。
        ClientCAs *x509.CertPool

        // InsecureSkipVerify控制客户端是否验证
        // 服务器的证书链和主机名。
        // 如果InsecureSkipVerify为true,则TLS接受任何证书
        // 由服务器和该证书中的任何主机名提供。
        // 在这种模式下,TLS容易受到man-in-the-middle攻击。
        // 这应该仅用于测试。
        InsecureSkipVerify bool

        // CipherSuites是受支持的密码套件列表。 如果是CipherSuites
        // 是零,TLS使用实现支持的套件列表。
        CipherSuites []uint16

        // PreferServerCipherSuites控制服务器是否选择
        // 客户端最喜欢的密码套件,或服务器最优选的密码套件
        // 密码套件。 如果为true则为服务器的首选项,如表所示
        // 使用CipherSuites中元素的顺序。
        PreferServerCipherSuites bool

        // 可以将SessionTicketsDisabled设置为true以禁用会话票证
        // (恢复)支持。
        SessionTicketsDisabled bool

        // TLS服务器使用SessionTicketKey来提供会话
        // 恢复。 请参阅RFC 5077.如果为零,则将填充
        // 第一次服务器握手之前的随机数据。
        //
        // 如果多个服务器正在终止同一主机的连接
        // 他们都应该拥有相同的SessionTicketKey。 如果
        // SessionTicketKey泄漏,以前记录和未来的TLS
        // 使用该密钥的连接受到损害。
        SessionTicketKey [32]byte

        // SessionCache是TLS会话的ClientSessionState条目的缓存
        // 恢复。
        ClientSessionCache ClientSessionCache

        // MinVersion包含可接受的最小SSL/TLS版本。
        // 如果为零,则将TLS 1.0作为最小值。
        MinVersion uint16

        // MaxVersion包含可接受的最大SSL/TLS版本。
        // 如果为零,则使用此程序包支持的最大版本,
        // 目前是TLS 1.2。
        MaxVersion uint16

        // CurvePreferences包含将在其中使用的椭圆曲线
        // ECDHE握手,按优先顺序排列。 如果为空,则默认为
        // 被使用。
        CurvePreferences []CurveID

        // DynamicRecordSizingDisabled禁用TLS记录的自适应大小调整。
        // 如果为true,则始终使用最大可能的TLS记录大小。 当
        // false时,可以调整TLS记录的大小
        // 改善延迟。
        DynamicRecordSizingDisabled bool

        // 重新协商控制支持哪种类型的重新协商。
        // 对于绝大多数应用程序,默认值none都是正确的。
        Renegotiation RenegotiationSupport

        // KeyLogWriter可选择指定TLS主机密的目标
        // 在NSS密钥日志格式中,可用于允许外部程序
        // 比如Wireshark来解密TLS连接。
        // 请参阅https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format。
        // 使用KeyLogWriter会危及安全性,应该只是
        // 用于调试。
        KeyLogWriter io.Writer
        // 包含已过滤或未导出的字段
}

示例(KeyLogWriter)

代码:

// 通过解密网络流量捕获来调试TLS应用程序。

// 警告:使用KeyLogWriter会危及安全性,并且应该只是
// 用于调试。
// 虚假测试HTTP服务器的示例具有不安全的随机输出
// 重复性。
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
server.TLS = &tls.Config{
        Rand: zeroSource{}, // 仅举例来说; 不要这样做。
}
server.StartTLS()
defer server.Close()

// 通常,日志将转到打开的文件:
// w, err := os.OpenFile("tls-secrets.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
w := os.Stdout

client := &http.Client{
        Transport: &http.Transport{
                TLSClientConfig: &tls.Config{
                        KeyLogWriter: w,

                        Rand:               zeroSource{}, // 用于可重复的输出; 不要这样做。
                        InsecureSkipVerify: true,         // 测试服务器证书不受信任。
                },
        },
}
resp, err := client.Get(server.URL)
if err != nil {
        log.Fatalf("Failed to get URL: %v", err)
}
resp.Body.Close()

// 生成的文件可以与Wireshark一起使用来解密TLS
// 通过在SSL协议中设置(Pre)-Master-Secret日志文件名来连接
// 优先级。

输出:

CLIENT_RANDOM 0000000000000000000000000000000000000000000000000000000000000000 baca0df460a688e44ce018b025183cc2353ae01f89755ef766eedd3ecc302888ee3b3a22962e45f48c20df15a98c0e80

func (*Config) BuildNameToCertificate(查看源代码)

func (c *Config) BuildNameToCertificate()

BuildNameToCertificate 解析 c.Certificates 并从每个 leaf 证书的 CommonName 和 SubjectAlternateName 字段构建 c.NameToCertificate。

func (*Config) Clone(查看源代码)

func (c *Config) Clone() *Config

Clone 返回c的浅层 clone。克隆 TLS 客户端或服务器正在同时使用的配置是安全的。

func (*Config) SetSessionTicketKeys(查看源代码)

func (c *Config) SetSessionTicketKeys(keys [][32]byte)

SetSessionTicketKeys 更新服务器的会话票证密钥。创建新票时将使用第一个键,而所有键都可用于解密票。在服务器运行时调用此函数以便旋转会话票据密钥是安全的。如果键为空,该功能将会出现混乱。

type Conn(查看源代码)

Conn 代表安全连接。它实现了 net.Conn 接口。

type Conn struct {
        // 包含已过滤或未导出的字段
}

func Client(查看源代码)

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

客户端使用 conn 作为底层传输返回新的 TLS 客户端连接。配置不能为零:用户必须在配置中设置 ServerName 或 InsecureSkipVerify。

func Dial(查看源代码)

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

拨号使用 net.Dial 连接到给定的网络地址,然后启动 TLS handshake,返回生成的 TLS 连接。拨号将零配置解释为等同于零配置;请参阅 Config 的文档以了解默认值。

示例

package main

import (
	"crypto/tls"
	"crypto/x509"
)

func main() {
	// 使用自定义根证书集连接。

	const rootPEM = `
-----BEGIN CERTIFICATE-----
MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG
EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7
qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD
VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g
K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI
KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n
ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB
BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY
/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/
zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza
HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto
WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6
yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx
-----END CERTIFICATE-----`

	// 首先,创建一组根证书。 对于这个例子我们只
	// 有一个。 也可以省略这个以便使用
	// 当前操作系统的默认根集。
	roots := x509.NewCertPool()
	ok := roots.AppendCertsFromPEM([]byte(rootPEM))
	if !ok {
		panic("failed to parse root certificate")
	}

	conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{
		RootCAs: roots,
	})
	if err != nil {
		panic("failed to connect: " + err.Error())
	}
	conn.Close()
}

func DialWithDialer(查看源代码)

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

DialWithDialer 使用 dialer.Dial 连接到给定的网络地址,然后启动TLS handshake,返回生成的 TLS 连接。拨号程序中给出的任何超时或截止日期都适用于连接和 TLS handshake。

DialWithDialer 将零配置解释为等同于零配置;请参阅 Config 的文档以了解默认值。

func Server(查看源代码)

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

服务器返回一个新的 TLS 服务器端连接,使用 conn 作为底层传输。配置配置必须非零,并且必须包含至少一个证书或者设置 GetCertificate。

func (*Conn) Close(查看源代码)

func (c *Conn) Close() error

Close 关闭连接。

func (*Conn) CloseWrite(查看源代码)

func (c *Conn) CloseWrite() error

CloseWrite 关闭连接的写入侧。只有在 handshake 完成后才能调用,并且不会在基础连接上调用 CloseWrite。大多数调用者应该只使用关闭。

func (*Conn) ConnectionState(查看源代码)

func (c *Conn) ConnectionState() ConnectionState

ConnectionState 返回有关连接的基本 TLS 详细信息。

func (*Conn) Handshake(查看源代码)

func (c *Conn) Handshake() error

如果尚未运行,handshake 会运行客户端或服务器 handshake 协议。这个包的大部分使用都不需要明确调用 Handshake:第一个Read 或 Write 会自动调用。

func (*Conn) LocalAddr(查看源代码)

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

LocalAddr 返回本地网络地址。

func (*Conn) OCSPResponse(查看源代码)

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

OCSPResponse 返回来自 TLS 服务器的已装订的 OCSP 响应(如果有)。(仅对客户端连接有效。)

func (*Conn) Read(查看源代码)

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

可以使读超时并返回一个 net.Error Timeout()== true 在一个固定的时间限制后; 请参阅 SetDeadline 和 SetReadDeadline。

func (*Conn) RemoteAddr(查看源代码)

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

RemoteAddr 返回远程网络地址。

func (*Conn) SetDeadline(查看源代码)

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

SetDeadline 设置与连接关联的读取和写入最后期限。t 表示读取和写入不会超时。写入超时后,TLS 状态已损坏,所有将来的写入都将返回相同的错误。

func (*Conn) SetReadDeadline(查看源代码)

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

SetReadDeadline 设置底层连接的读取最后期限。t 代表零值表示Read 不会超时。

func (*Conn) SetWriteDeadline(查看源代码)

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

SetWriteDeadline 设置底层连接的写入截止时间。t 的零值意味着Write 不会超时。写入超时后,TLS 状态已损坏,所有将来的写入都将返回相同的错误。

func (*Conn) VerifyHostname(查看源代码)

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

VerifyHostname 检查对等证书链对于连接到主机是否有效。如果是,则返回零;如果不是,则返回描述问题的错误。

func (*Conn) Write(查看源代码)

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

Write 将数据写入连接。

type ConnectionState(查看源代码)

ConnectionState 记录有关连接的基本 TLS 详细信息。

type ConnectionState struct {
        Version                     uint16                // 连接使用的TLS版本(例如VersionTLS12)
        HandshakeComplete           bool                  // TLS握手完成
        DidResume                   bool                  // 连接恢复以前的TLS连接
        CipherSuite                 uint16                // 正在使用的密码套件(TLS_RSA_WITH_RC4_128_SHA,...)
        NegotiatedProtocol          string                // 协商下一个协议(不保证来自Config.NextProtos)
        NegotiatedProtocolIsMutual  bool                  // 协商协议由服务器公布(仅限客户端)
        ServerName                  string                // 客户端请求的服务器名称(如果有)(仅限服务器端)
        PeerCertificates            []*x509.Certificate   // 远程同行提供的证书链
        VerifiedChains              [][]*x509.Certificate // 经过验证的PeerCertificates链
        SignedCertificateTimestamps [][]byte              // 来自服务器的SCT,如果有的话
        OCSPResponse                []byte                // 来自服务器的装订OCSP响应(如果有)
        // TLSUnique包含“tls-unique”通道绑定值(请参阅RFC
        // 5929,第3节)。 对于恢复的会话,此值将为零
        // 因为恢复不包括足够的背景(参见
        // https://mitls.org/pages/attacks/3SHAKE#channelbindings)。
        // 一旦TLS主秘密修复具有,将在Go的未来版本中进行更改
        // 已经标准化和实施。
        TLSUnique []byte
}

type CurveID(查看源代码)

CurveID 是椭圆曲线的 TLS 标识符的类型。请参阅http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8

type CurveID uint16
const (
        CurveP256 CurveID = 23
        CurveP384 CurveID = 24
        CurveP521 CurveID = 25
        X25519    CurveID = 29
)

type RecordHeaderError(查看源代码)

当TLS记录标题无效时,RecordHeaderError 产生结果。

type RecordHeaderError struct {
        // Msg包含描述错误的人类可读字符串。
        Msg string
        // RecordHeader包含五个字节的TLS记录头
        // 触发了错误。
        RecordHeader [5]byte
}

func (RecordHeaderError) Error(查看源代码)

func (e RecordHeaderError) Error() string

type RenegotiationSupport(查看源代码)

重新协商支持列举了 TLS 重新协商的不同级别的支持。TLS 重新协商是在第一次连接之后对连接执行后续握手的行为。这使状态机非常复杂,并且成为众多细微安全问题的根源。不支持启动重新协商,但可以启用对接受重新协商请求的支持。

即使启用,服务器也不能在握手之间更改其身份(即叶​​证书必须相同)。此外,不允许同时握手和应用程序数据流,因此重新协商只能用于与重新协商同步的协议,例如 HTTPS。

type RenegotiationSupport int
const (
        // RenegotiateNever禁用重新协商。
        RenegotiateNever RenegotiationSupport = iota

        // RenegotiateOnceAsClient允许远程服务器请求
        // 每次连接重新协商一次。
        RenegotiateOnceAsClient

        // RenegotiateFreelyAsClient允许重复使用远程服务器
        // 请求重新谈判。
        RenegotiateFreelyAsClient
)

type SignatureScheme(查看源代码)

SignatureScheme 标识TLS支持的签名算法。请参阅https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.3。

type SignatureScheme uint16
const (
        PKCS1WithSHA1   SignatureScheme = 0x0201
        PKCS1WithSHA256 SignatureScheme = 0x0401
        PKCS1WithSHA384 SignatureScheme = 0x0501
        PKCS1WithSHA512 SignatureScheme = 0x0601

        PSSWithSHA256 SignatureScheme = 0x0804
        PSSWithSHA384 SignatureScheme = 0x0805
        PSSWithSHA512 SignatureScheme = 0x0806

        ECDSAWithP256AndSHA256 SignatureScheme = 0x0403
        ECDSAWithP384AndSHA384 SignatureScheme = 0x0503
        ECDSAWithP521AndSHA512 SignatureScheme = 0x0603
)

Bugs

  • ☞ crypto/tls包只针对实现对CBC模式加密Lucky13攻击的对策,只有对SHA1变种。见http://www.isg.rhul.ac.uk/tls/TLStiming.pdf和https://www.imperialviolet.org/2013/02/04/luckythirteen.html。
Go

Go 是一种编译型语言,它结合了解释型语言的游刃有余,动态类型语言的开发效率,以及静态类型的安全性。它也打算成为现代的,支持网络与多核计算的语言。要满足这些目标,需要解决一些语言上的问题:一个富有表达能力但轻量级的类型系统,并发与垃圾回收机制,严格的依赖规范等等。这些无法通过库或工具解决好,因此Go也就应运而生了。

主页 https://golang.org/
源码 https://go.googlesource.com/go
发布版本 1.9.2

Go目录

1.档案 | archive
2.缓冲区 | bufio
3.内置 | builtin
4.字节 | bytes
5.压缩 | compress
6.容器 | container
7.上下文 | context
8.加密 | crypto
9.数据库 | database
10.调试 | debug
11.编码 | encoding
12.错误 | errors
13. expvar
14.flag
15. fmt
16. go
17.散列 | hash
18.html
19.图像 | image
20.索引 | index
21.io
22.日志 | log
23.数学 | math
24. math/big
25.math/bits
26.math/cmplx
27.math/rand
28.拟态 | mime
29.net
30.net/http
31. net/mail
32. net/rpc
33.net/smtp
34. net/textproto
35. net/url
36.os
37.路径 | path
38.插件 | plugin
39.反射 | reflect
40.正则表达式 | regexp
41.运行时 | runtime
42.排序算法 | sort
43.转换 | strconv
44.字符串 | strings
45.同步 | sync
46.系统调用 | syscall
47.测试 | testing
48.文本 | text
49.时间戳 | time
50.unicode
51.不安全性 | unsafe
52.Go 语言数据类型
53.Go 语言基础语法
54.Go 语言结构
55.Go 语言 select 语句
56.Go 语言 switch 语句
57.Go 语言 if 语句嵌套
58.Go 语言 if…else 语句
59.Go 语言 if 语句
60.Go 语言运算符
61.Go 语言常量
62.Go 语言函数闭包
63.Go 语言函数作为实参
64.Go 语言函数引用传递值
65.Go 语言函数值传递值
66.Go 语言函数
67.Go 语言 goto 语句
68.Go 语言 continue 语句
69.Go 语言 break 语句
70.Go 语言循环嵌套
71.Go 语言 for 循环
72.Go 语言结构体
73.Go 语言指针作为函数参数
74.Go 语言指向指针的指针
75.Go 语言指针数组
76.Go 语言指针
77.Go 语言向函数传递数组
78.Go 语言多维数组
79.Go 语言变量作用域
80.Go 语言函数方法
81.Go 错误处理
82.Go 语言接口
83.Go 语言类型转换
84.Go 语言递归函数
85.Go 语言Map(集合)
86.Go 语言范围(Range)
87.Go 语言切片(Slice)
88.Go 并发
89.Go fmt.Sprintf 格式化字符串