doc: 重新编排

This commit is contained in:
Sun Yimin 2023-12-13 08:02:22 +08:00 committed by GitHub
parent 2187bea0d9
commit fefb280170
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 25 deletions

View File

@ -1,4 +1,6 @@
# 参考标准
# SM2椭圆曲线公钥密码算法应用指南
## 参考标准
* 《GB/T 32918.1-2016 信息安全技术 SM2椭圆曲线公钥密码算法 第1部分总则》
* 《GB/T 32918.2-2016 信息安全技术 SM2椭圆曲线公钥密码算法 第2部分数字签名算法》
* 《GB/T 32918.3-2016 信息安全技术 SM2椭圆曲线公钥密码算法 第3部分密钥交换协议》
@ -8,7 +10,7 @@
您可以从[国家标准全文公开系统](https://openstd.samr.gov.cn/)在线阅读这些标准。
# 概述
## 概述
既然是椭圆曲线公钥密码算法它就和NIST P系列椭圆曲线公钥密码算法类似特别是P-256。NIST P 系列椭圆曲线公钥密码算法主要用于数字签名和密钥交换NIST没有定义基于椭圆曲线的公钥加密算法标准[SEC 1: Elliptic Curve Cryptography](https://www.secg.org/sec1-v2.pdf)第五章定义了“Elliptic Curve Integrated Encryption Scheme (ECIES)”,不过应用不广。感兴趣的同学可以进一步对比一下:
| SM2 | SEC 1 |
@ -17,10 +19,10 @@
| 密钥交换协议 | ECMQV |
| 公钥加密算法 | ECIES |
# SM2公私钥对
## SM2公私钥对
SM2公私钥对的话要么是自己产生要么是别的系统产生后通过某种方式传输给您的。
## SM2公私钥对的生成
### SM2公私钥对的生成
您可以通过调用```sm2.GenerateKey```方法产生SM2公私钥对SM2的私钥通过组合方式扩展了```ecdsa.PrivateKey```用于定义一些SM2特定的方法
```go
// PrivateKey represents an ECDSA SM2 private key.
@ -31,7 +33,7 @@ type PrivateKey struct {
```
SM2的公钥类型沿用了```ecdsa.PublicKey```结构。
## SM2公钥的解析、构造
### SM2公钥的解析、构造
通常情况下公钥是通过PEM编码的文本传输的您可以通过两步获得公钥
* 获得PEM中的block
* 解析block中的公钥
@ -57,7 +59,7 @@ func getPublicKey(pemContent []byte) (any, error) {
```
当然您也可以使用ecdh包下的方法```ecdh.P256().NewPublicKey```来构造,目前只支持非压缩方式。
## SM2私钥的解析、构造
### SM2私钥的解析、构造
私钥的封装格式主要有以下几种,[相关讨论](https://github.com/emmansun/gmsm/issues/104)
* RFC 5915 / SEC1 - http://www.secg.org/sec1-v2.pdf
* PKCS#12
@ -89,7 +91,7 @@ func getPublicKey(pemContent []byte) (any, error) {
```
当然你也可以使用ecdh包的方法```ecdh.P256().NewPrivateKey```来构造私钥您要确保输入的字节数组是256位16字节如果不是请先自行处理。
# 数字签名算法
## 数字签名算法
您可以直接使用sm2私钥的签名方法```Sign```
```go
// This is a reference method to force SM2 standard with SDK [crypto.Signer].
@ -138,10 +140,10 @@ func ExampleVerifyASN1WithSM2() {
}
```
# 密钥交换协议
## 密钥交换协议
这里有两个实现一个是传统实现位于sm2包中另外一个参考最新go语言的实现在ecdh包中。在这里不详细介绍使用方法一般只有tls/tlcp才会用到普通应用通常不会涉及这一块感兴趣的话可以参考github.com/Trisia/gotlcp中的应用。
# 公钥加密算法
## 公钥加密算法
请牢记非对称加密算法通常不用于加密大量数据而是用来加密对称加密密钥我们在tlcp以及信封加密机制中能找到这种用法。
SM2公钥加密算法支持的密文编码格式有两种
@ -204,7 +206,7 @@ func ExamplePrivateKey_Decrypt() {
具体API文档请参考[API Document](https://godoc.org/github.com/emmansun/gmsm)
# 与KMS集成
## 与KMS集成
国内云服务商的KMS服务大都提供SM2密钥我们一般调用其API进行签名和解密而验签和加密操作一般在本地用公钥即可完成。不过需要注意的是KMS提供的签名通常需要您在本地进行hash操作而sm2签名的hash又比较特殊下面示例供参考将在下个发布版本**v0.24.0**中公开此函数```sm2.CalculateSM2Hash```
```go
func calculateSM2Hash(pub *ecdsa.PublicKey, data, uid []byte) ([]byte, error) {

View File

@ -1,12 +1,13 @@
# 参考标准
# SM3密码杂凑算法
## 参考标准
* 《GB/T 32905-2016 信息安全技术 SM3密码杂凑算法》
您可以从[国家标准全文公开系统](https://openstd.samr.gov.cn/)在线阅读此标准。
# 概述
## 概述
SM3密码杂凑算法或者叫SM3哈希算法它是一个输出结果为256位32字节的哈希算法。在本软件库中SM3的实现方法签名与Go语言中的哈希算法特别是SHA256保持一致所以用法也是一样的。具体API文档包括Example请参考[API Document](https://godoc.org/github.com/emmansun/gmsm)。
# 常用用法示例
## 常用用法示例
```go
// 直接使用sm3.Sum方法
func ExampleSum() {
@ -40,6 +41,6 @@ func ExampleNew_file() {
}
```
# 性能
## 性能
请参考[SM3密码杂凑算法性能优化](https://github.com/emmansun/gmsm/wiki/SM3%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96)。

View File

@ -1,13 +1,14 @@
# 参考标准
# SM4分组密码算法应用指南
## 参考标准
* 《GB/T 32907-2016 信息安全技术 SM4分组密码算法》
* 《GB/T 17964-2021 信息安全技术 分组密码算法的工作模式》
您可以从[国家标准全文公开系统](https://openstd.samr.gov.cn/)在线阅读这些标准。
# 概述
## 概述
SM4分组密码算法其地位类似NIST中的AES分组密码算法密钥长度128位16字节分组大小也是128位16字节。在本软件库中SM4的实现与Go语言中的AES实现一致也实现了```cipher.Block```接口所以所有Go语言中实现的工作模式CBC/GCM/CFB/OFB/CTR都能与SM4组合使用。
# [工作模式](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation)
## [工作模式](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation)
Go语言实现的工作模式主要有三类
* 基于分组的工作模式 ```cipher.BlockMode```譬如CBC。
* 带有关联数据的认证加密工作模式```cipher.AEAD```譬如GCM。
@ -28,10 +29,11 @@ Go语言实现的工作模式主要有三类
目前本软件库的SM4针对ECB/CBC/GCM/XTS工作模式进行了绑定组合性能优化暂时没有计划使用汇编优化HCTR模式HCTR模式可以采用和GCM类似的方法进行汇编优化
**使用建议**常用的对称加解密应用场合推荐优先使用GCM模式其次CBC模式一些安全扫描工具也会把CBC工作模式列为安全性不高的工作模式。我能想到的GCM模式的缺点是加解密的相关方不支持GCM模式或者实现性能不好。
### 使用建议
常用的对称加解密应用场合推荐优先使用GCM模式其次CBC模式一些安全扫描工具也会把CBC工作模式列为安全性不高的工作模式。我能想到的GCM模式的缺点是加解密的相关方不支持GCM模式或者实现性能不好。
# 填充padding
## 填充padding
有些分组密码算法的工作模式(譬如实现了```cipher.BlockMode```接口的模式的输入要求是其长度必须是分组大小的整数倍。《GB/T 17964-2021 信息安全技术 分组密码算法的工作模式》附录C中列出了以下几种填充模式
* 填充方式 1对应本软件库的```padding.NewPKCS7Padding```
* 填充方式 2对应本软件库的```padding.NewISO9797M2Padding```
@ -41,7 +43,7 @@ Go语言实现的工作模式主要有三类
您如果使用实现了```cipher.BlockMode```接口的分组加密工作模式那您也必须与相关方协调好填充模式。JAVA库的对称加密算法字符串名就包含了所有信息譬如**AES/CBC/PKCS7Padding**。
# 密文及其相关参数的传输和存储
## 密文及其相关参数的传输和存储
如果是自描述的那肯定有相关标准定义相关ASN.1结构并且给分组密码算法、工作模式、填充方式都赋予一个OID。
如果是内部服务之间,可能是在应用/服务级别自定义所使用分组密码算法、工作模式、填充方式的标识作为应用的METADATA也就是加密用的METADATA和密文分离。
@ -56,10 +58,10 @@ Go语言实现的工作模式主要有三类
至于要将二进制转为文本传输、存储编个码就行标准base64 / URL base64 / HEX事先协调、定义好就可以了。这里顺便推荐一下[性能更好的BASE64实现](https://github.com/emmansun/base64)。
# API文档及示例
## API文档及示例
这里只列出GCM/CBC的例子其余请参考[API Document](https://godoc.org/github.com/emmansun/gmsm)。
## GCM示例
### GCM示例
```go
func Example_encryptGCM() {
// Load your secret key from a safe place and reuse it across multiple
@ -120,7 +122,7 @@ func Example_decryptGCM() {
}
```
## CBC示例
### CBC示例
```go
func Example_encryptCBC() {
// Load your secret key from a safe place and reuse it across multiple
@ -192,7 +194,7 @@ func Example_decryptCBC() {
// Output: sm4 exampleplaintext
}
```
# 性能
## 性能
SM4分组密码算法的软件高效实现不算CPU指令支持的话已知有如下几种方法
* S盒和L转换预计算
* SIMD并行处理并行查表
@ -201,7 +203,7 @@ SM4分组密码算法的软件高效实现不算CPU指令支持的话
当然这些与有CPU指令支持的AES算法相比性能差距依然偏大要是工作模式不支持并行差距就更巨大了。
# 与KMS集成
## 与KMS集成
可能您会说如果我在KMS中创建了一个SM4对称密钥就不需要本地加解密了这话很对不过有种场景会用到
* 在KMS中只创建非对称密钥KEK
* 对称加解密在本地进行;