From 2ead6d523d07c22821c5cece6e31a28dddc8a5f6 Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Tue, 25 Jun 2024 17:41:14 +0800 Subject: [PATCH] doc: add pkcs12 --- README.md | 1 + docs/pkcs12.md | 165 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 docs/pkcs12.md diff --git a/README.md b/README.md index 332beb5..fdb8add 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Go语言商用密码软件,简称**GMSM**,一个安全、高性能、易于 * [SM9标识密码算法应用指南](./docs/sm9.md) * [CFCA互操作性指南](./docs/cfca.md) * [PKCS7应用指南](./docs/pkcs7.md) +* [PKCS12应用指南](./docs/pkcs12.md) ## 包结构 * **SM2** - SM2椭圆曲线公钥密码算法,曲线的具体实现位于[internal/sm2ec](https://github.com/emmansun/gmsm/tree/main/internal/sm2ec) package中。SM2曲线实现性能和Golang SDK中的NIST P256椭圆曲线原生实现(非BoringCrypto)类似,也对**amd64** 和 **arm64**架构做了专门汇编优化实现,您也可以参考[SM2实现细节](https://github.com/emmansun/gmsm/wiki/SM2%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96)及相关Wiki和代码,以获得更多实现细节。SM2包实现了SM2椭圆曲线公钥密码算法的数字签名算法、公钥加密算法、密钥交换算法,以及《GB/T 35276-2017信息安全技术 SM2密码算法使用规范》中的密钥对保护数据格式。 diff --git a/docs/pkcs12.md b/docs/pkcs12.md new file mode 100644 index 0000000..853c753 --- /dev/null +++ b/docs/pkcs12.md @@ -0,0 +1,165 @@ +# [go-pkcs12](https://github.com/emmansun/go-pkcs12)应用指南 +[PKCS #12: Personal Information Exchange Syntax v1.1](https://datatracker.ietf.org/doc/html/rfc7292),PKCS12目前似乎没有相应的国密标准。 +定制PKCS12的目的是: +1. 可以处理SM2私钥和证书。 +2. 可以替代、使用一些商密算法,主要是SM3和SM4。 + +## PKCS#12的解析 +[go-pkcs12](https://github.com/emmansun/go-pkcs12)提供三个方法: + +| 方法 | 适用 | 具体说明 | +| :--- | :--- | :--- | +| ```DecodeChain``` | 抽取出一个私钥、一个相应证书以及证书链 | 私钥和相应证书必须存在,否则报错 | +| ```Decode``` | 抽取出一个私钥、一个相应证书 | 私钥和相应证书必须存在,否则报错;并且**不能有证书链存在**。 | +| ```DecodeTrustStore``` | 抽取出证书链 | 只支持java的TrustStore, [Difference Between a Java Keystore and a Truststore](https://www.baeldung.com/java-keystore-truststore-difference) | + +### 解码能处理的算法 + +#### 证书及私钥加密算法 +**PKCS12算法**: +* pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} +* pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} +* pbewithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} + +不同于PKCS#5 v1.5中的PBES1,上述这些是PKCS#12的独有算法,特别是它的KDF和密码处理。 + +**PBES2** +由两部分组成,分别为**KDF**和加密算法。目前KDF只支持KDF2, KDF2中支持的PRF方法有: +* id-hmacWithSHA1 +* id-hmacWithSHA256 +* id-hmacWithSM3 + +具体可参考[PKCS #5: Password-Based Cryptography Specification Version 2.1](https://datatracker.ietf.org/doc/html/rfc8018) + +加密算法有: +* AES-CBC-Pad,密钥长度支持16/24/32字节 +* SM4-CBC-Pad,密钥长度支持16字节 + +#### 数据完整性保护 +这里只支持基于密码的完整性保护:HMAC。支持的HASH算法有: +* SHA1 +* SHA256 +* SM3 + +## PKCS#12的生成 +目前只支持下列几种,不支持自由定义: + +* ```LegacyRC2```,加密使用PKCS12特有算法;对证书使用RC2加密,对私钥使用3DES加密,一致性保证使用HMAC-SHA1。 +* ```LegacyDES```,加密使用PKCS12特有算法;对证书和私钥都是用3DES加密,一致性保证使用HMAC-SHA1。 +* ```Passwordless```,无加密、一致性保证模式。 +* ```Modern2023```,对应OpenSSL 3+ 默认,加密使用AES-256-CBC with PBKDF2,一致性保证使用HMAC-SHA256。 +* ```ShangMi2024```,这个估计目前没什么互操作性。 + +目前的全局函数```Encode``` / ```EncodeTrustStore```使用**LegacyRC2**编码器。 + +```go +// LegacyRC2 encodes PKCS#12 files using weak algorithms that were +// traditionally used in PKCS#12 files, including those produced +// by OpenSSL before 3.0.0, go-pkcs12 before 0.3.0, and Java when +// keystore.pkcs12.legacy is defined. Specifically, certificates +// are encrypted using PBE with RC2, and keys are encrypted using PBE +// with 3DES, using keys derived with 2048 iterations of HMAC-SHA-1. +// MACs use HMAC-SHA-1 with keys derived with 1 iteration of HMAC-SHA-1. +// +// Due to the weak encryption, it is STRONGLY RECOMMENDED that you use [DefaultPassword] +// when encoding PKCS#12 files using this encoder, and protect the PKCS#12 files +// using other means. +// +// By default, OpenSSL 3 can't decode PKCS#12 files created using this encoder. +// For better compatibility, use [LegacyDES]. For better security, use +// [Modern2023]. +var LegacyRC2 = &Encoder{ + macAlgorithm: oidSHA1, + certAlgorithm: oidPBEWithSHAAnd40BitRC2CBC, + keyAlgorithm: oidPBEWithSHAAnd3KeyTripleDESCBC, + kdfPrf: nil, + encryptionScheme: nil, + macIterations: 1, + encryptionIterations: 2048, + saltLen: 8, + rand: rand.Reader, +} + +// LegacyDES encodes PKCS#12 files using weak algorithms that are +// supported by a wide variety of software. Certificates and keys +// are encrypted using PBE with 3DES using keys derived with 2048 +// iterations of HMAC-SHA-1. MACs use HMAC-SHA-1 with keys derived +// with 1 iteration of HMAC-SHA-1. These are the same parameters +// used by OpenSSL's -descert option. As of 2023, this encoder is +// likely to produce files that can be read by the most software. +// +// Due to the weak encryption, it is STRONGLY RECOMMENDED that you use [DefaultPassword] +// when encoding PKCS#12 files using this encoder, and protect the PKCS#12 files +// using other means. To create more secure PKCS#12 files, use [Modern2023]. +var LegacyDES = &Encoder{ + macAlgorithm: oidSHA1, + certAlgorithm: oidPBEWithSHAAnd3KeyTripleDESCBC, + keyAlgorithm: oidPBEWithSHAAnd3KeyTripleDESCBC, + kdfPrf: nil, + encryptionScheme: nil, + macIterations: 1, + encryptionIterations: 2048, + saltLen: 8, + rand: rand.Reader, +} + +// Passwordless encodes PKCS#12 files without any encryption or MACs. +// A lot of software has trouble reading such files, so it's probably only +// useful for creating Java trust stores using [Encoder.EncodeTrustStore] +// or [Encoder.EncodeTrustStoreEntries]. +// +// When using this encoder, you MUST specify an empty password. +var Passwordless = &Encoder{ + macAlgorithm: nil, + certAlgorithm: nil, + keyAlgorithm: nil, + kdfPrf: nil, + encryptionScheme: nil, + rand: rand.Reader, +} + +// Modern2023 encodes PKCS#12 files using algorithms that are considered modern +// as of 2023. Private keys and certificates are encrypted using PBES2 with +// PBKDF2-HMAC-SHA-256 and AES-256-CBC. The MAC algorithm is HMAC-SHA-2. These +// are the same algorithms used by OpenSSL 3 (by default), Java 20 (by default), +// and Windows Server 2019 (when "stronger" is used). +// +// Files produced with this encoder can be read by OpenSSL 1.1.1 and higher, +// Java 12 and higher, and Windows Server 2019 and higher. +// +// For passwords, it is RECOMMENDED that you do one of the following: +// 1) Use [DefaultPassword] and protect the file using other means, or +// 2) Use a high-entropy password, such as one generated with `openssl rand -hex 16`. +// +// You SHOULD NOT use a lower-entropy password with this encoder because the number of KDF +// iterations is only 2048 and doesn't provide meaningful protection against +// brute-forcing. You can increase the number of iterations using [Encoder.WithIterations], +// but as https://neilmadden.blog/2023/01/09/on-pbkdf2-iterations/ explains, this doesn't +// help as much as you think. +var Modern2023 = &Encoder{ + macAlgorithm: oidSHA256, + certAlgorithm: oidPBES2, + keyAlgorithm: oidPBES2, + kdfPrf: oidHmacWithSHA256, + encryptionScheme: oidAES256CBC, + macIterations: 2048, + encryptionIterations: 2048, + saltLen: 16, + rand: rand.Reader, +} + +// ShangMi2024 encodes PKCS#12 files using algorithms that are all ShangMi. +// Private keys and certificates are encrypted using PBES2 with PBKDF2-HMAC-SM3 and SM4-CBC. +// The MAC algorithm is HMAC-SM3. +var ShangMi2024 = &Encoder{ + macAlgorithm: oidSM3, + certAlgorithm: oidPBES2, + keyAlgorithm: oidPBES2, + kdfPrf: oidHmacWithSM3, + encryptionScheme: oidSM4CBC, + macIterations: 2048, + encryptionIterations: 2048, + saltLen: 16, + rand: rand.Reader, +} +```