朝花夕拾 - Transport Layer Security
0x1. TLS 如何握手?
TLS 握手流程
具体流程:
Client Hello
客户端发送 Client hello 给服务器,包含协议版本号,客户端随机数,支持的密码套件(例如TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) 等信息
Server Hello
服务器收到 Client Hello 信息后, 服务器回复 Server Hello 给客户端,包含服务器随机数,服务器选择的加密套件,服务器证书等信息
交换密钥
a. 客户端验证服务器的证书合法后,生成预主密钥, 通过服务器公钥加密后发给服务器
b. 服务器用私钥解密,获得预主密钥;客户端,服务器用 客户端随机码,服务器随机码,预主密钥生成会话密钥,后续通讯用该会话密钥加密;
c. 握手结束
0x2. 证书里面有什么?
证书是 X.509 格式,主要包含公钥,颁发机构 (CA),签名,过期时间等信息,证书的常见后缀有 CRT (linux/unix),CER (windows),KEY (包含公钥,私钥),其内部采用 DER 或者 PEM 来编码;
PEM
PEM 可以用来表示证书,公钥,私钥,PEM 是一串字符串,由 “ ——xxxx—— + base64(内容) + ——xxxx—— “ 组成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27-----BEGIN CERTIFICATE-----
MIIEqjCCApKgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAweDELMAkGA1UEBhMCR0Ix
DjAMBgNVBAgMBUNoaW5hMQ0wCwYDVQQKDARBSVNBMScwJQYDVQQLDB5BSVNBIEx0
ZCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxITAfBgNVBAMMGEFJU0EgTHRkIEludGVy
bWVkaWF0ZSBDQTAeFw0xOTExMjIxMDQyNDNaFw0yMDEyMDExMDQyNDNaMGExCzAJ
BgNVBAYTAkdCMQswCQYDVQQIDAJVUzENMAsGA1UECgwEQUlTQTEcMBoGA1UECwwT
QUlTQSBMdGQgV2ViIFNlcnZlcjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMFww
DQYJKoZIhvcNAQEBBQADSwAwSAJBALwxhAYBLf4E9qR+2/JpR+3XtV7FEeBJvbqI
og5sxcNPIWS5AYA7GTHDjtB0eYD4LpkzngCkWdCN0maAxFSr2YECAwEAAaOCARsw
ggEXMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQm
FiRPcGVuU1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYE
FGQjUZqxYMW8116UcXzsmgcZxorGMH4GA1UdIwR3MHWAFAsw88HU63rhDnopu9HR
s8MaDX87oVmkVzBVMQswCQYDVQQGEwJHQjEOMAwGA1UECAwFQ2hpbmExDTALBgNV
BAoMBEFJU0ExJzAlBgNVBAsMHkFJU0EgTHRkIENlcnRpZmljYXRlIEF1dGhvcml0
eYICEAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG
SIb3DQEBCwUAA4ICAQBkvyM+2w4cJW2G4YxEM44y1bgJ8o1SfRmami1DBSygj3gz
7TqPteuxJAlm6/ylp5+RO8TKdszMzTRCHfZ0rOp8CbwXSaDM7LdQ+nZchtFh7371
cCDLAW3d9g4hvZE1EnPspT1fs3pUV9npeqDA4CFSNup7PHVmhyAtTnSG1mC5Qac5
2Q9OQ463UVVmnd7HgFAyfuokPA3Cz24fSCUQHWHja9T06KAd+V48eM+9wo3lUNJO
FV1roSLmT4jMrC+znRsovhObjfI5HNZCR2yeiwnedPMt5c6OWEGr8vXvJ/4TW0oR
S3knGIBw8/VsXIBT/LiQN6CPfKmnMKPycI33+g0oShdu1x9yc1kGg+Kr2r1uMRGw
qFH6UcsD3RfGq22u8g+5jWBppZeCK78JphgqgrGQNfstcM2qeRiq7u63q2aXyj3n
ep+ajP7hPcswnziS8TAMo61U7iiBSVcA7zwM9CJ3Rocon+p1emDBiygBMfmF9XZr
LuLLnpWsEdxw8YfKm8V1EBHFPeFpNtQj5SpfYqwYPZ5cI8sApJ+fPlo5Ix84L9/D
VJx1QsQyVudJ1x8VX3eUtCTrBgmwvQoH+uvpW151ys0N9HityBaAdPSW6SI/6bqM
a1wUM0OZLmbmJndlODUgimy2bhxjNOUIfuX9gC3RN9U3D3B8aV5ZDSvUZWOrxQ==
-----END CERTIFICATE-----DER
Base64 解码 PEM 格式中间的内容,得到如下二进制数据,DER 是一种二进制编码格式。
1
30 82 04 aa 30 82 02 92 a0 03 02 01 02 02 02 10 01 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 78 31 0b 30 09 06 03 55 04 06 13 02 47 42 31 0e 30 0c 06 03 55 04 08 0c 05 43 68 69 6e 61 31 0d 30 0b 06 03 55 04 0a 0c 04 41 49 53 41 31 27 30 25 06 03 55 04 0b 0c 1e 41 49 53 41 20 4c 74 64 20 43 65 72 74 69 66 69 63 61 74 65 20 41 75 74 68 6f 72 69 74 79 31...
X.509
解码 DER 可以得到 X.509, X.509 利用 ASN.1 来描述其数据结构。
1
2
3
4
5
6
7
8
9
10
11
12SEQUENCE {
SEQUENCE {
[0] {
INTEGER 0x02 (2 decimal)
}
INTEGER 0x1001 (4097 decimal)
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.1.11 (sha256WithRSAEncryption)
NULL
}
...
}ASN.1
ASN.1 定义了一套描述数据的规则,ASN.1 与 DER 的关系,有点像 Unicode 和 UTF-8 的关系,ASN.1 只是一套描述规则,没有定义具体的编码方式,而 DER 是 ASN.1 最常用的编码方式;
用 ANS.1 表示一个 Foo 协议
1
2
3
4
5
6
7
8
9
10
11
12FooProtocol DEFINITIONS ::= BEGIN
FooQuestion ::= SEQUENCE {
trackingNumber INTEGER,
question IA5String
}
FooAnswer ::= SEQUENCE {
questionNumber INTEGER,
answer BOOLEAN
}
ENDASN.1, X.509, DER, PEM 关系示意图
0x3. Openssl 操作示例
生成 RSA 私钥
1
2
3openssl genrsa -out private.pem 512
注:为简单起见,使用 512 位的密钥;生产环境中请使用 2048 位密钥private.pem 是 PEM 格式,内容如下:
1
2
3
4
5
6
7
8
9-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBAKyymwzYcqw5MSHZFC2CoqctACyFdx4VuCo+mKiCgOW4JvMtcfhp
XCrU5QeHaBvbsVP0Yvf/EyUTqM3XCwaM+eUCAwEAAQJAa+h2BYLBtGdQEexINV+p
Lnhp4WfL1FqR5qOSU8inreFqeD+pOd/ZgdE+SmQfwIQwigiWIURlWgdxNxiXK8fy
SQIhANW7ipg1Bqpq/XBRtXmMAlDL/gbzW1JO9hNcBiKgakWzAiEAztmf9zkriOQ4
h2eSxy+QQKwDnJW1lCkLGLLCE9hBpgcCIQCes8YCpQURD6amexWMbkjd48r5MER0
Bouz7lXj6kde/wIhAMT6NrwNpCh69F31QrAN2jfL1rChXEXYA+okKG8PbAy3AiB8
hWCs2Qi+IB4uK1ZnQjE0KCmY5/DD4CCqZktkdBFZkw==
-----END RSA PRIVATE KEY-----提取公钥
1
openssl rsa -in private.pem -pubout -out pubkey.pem
pubkey.pem 内容如下:
1
2
3
4-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKyymwzYcqw5MSHZFC2CoqctACyFdx4V
uCo+mKiCgOW4JvMtcfhpXCrU5QeHaBvbsVP0Yvf/EyUTqM3XCwaM+eUCAwEAAQ==
-----END PUBLIC KEY-----提取 (n, e)
1
openssl rsa -inform PEM -text -noout -pubin < pubkey.pem
格式转换
PEM -> DER
1
2
3
4
5openssl rsa -in private.pem -outform DER -out private.der
查看 DER
xxd -l 16 -p private.der
3082013b020100024100acb29b0cd872DER -> PEM
1
openssl rsa -in private.der -inform DER -out private1.pem
提取 ASN.1
1
2
3
4
5
6
7
8openssl asn1parse -in public.key
0:d=0 hl=2 l= 92 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 75 prim: BIT STRING提取 n (prim: INTEGER)
1
2
3
4
5openssl asn1parse -strparse 17 -in pubkey.pem
0:d=0 hl=2 l= 72 cons: SEQUENCE
2:d=1 hl=2 l= 65 prim: INTEGER :ACB29B0CD872AC393121D9142D82A2A72D002C85771E15B82A3E98A88280E5B826F32D71F8695C2AD4E50787681BDBB153F462F7FF132513A8CDD70B068CF9E5
69:d=1 hl=2 l= 3 prim: INTEGER :010001