github.com/emmansun/gmsm@v0.29.1/docs/pkcs12.md (about) 1 # [go-pkcs12](https://github.com/emmansun/go-pkcs12)应用指南 2 [PKCS #12: Personal Information Exchange Syntax v1.1](https://datatracker.ietf.org/doc/html/rfc7292),PKCS12目前似乎没有相应的国密标准。 3 定制PKCS12的目的是: 4 1. 可以处理**SM2**私钥和证书。 5 2. 可以替代、使用一些商密算法,主要是**SM3**和**SM4**。 6 7 ## PKCS#12的解析 8 [go-pkcs12](https://github.com/emmansun/go-pkcs12)提供三个方法: 9 10 | 方法 | 适用 | 具体说明 | 11 | :--- | :--- | :--- | 12 | ```DecodeChain``` | 抽取出一个私钥、一个相应证书以及证书链 | 私钥和相应证书必须存在,否则报错 | 13 | ```Decode``` | 抽取出一个私钥、一个相应证书 | 私钥和相应证书必须存在,否则报错;并且**不能有证书链存在**。 | 14 | ```DecodeTrustStore``` | 抽取出证书链 | 只支持java的TrustStore, [Difference Between a Java Keystore and a Truststore](https://www.baeldung.com/java-keystore-truststore-difference) | 15 16 ### 解码能处理的算法 17 18 #### 证书及私钥加密算法 19 这里主要是**PBES(Password-Based Encryption Scheme)**, 它主要涉及几方面: 20 1. 密码处理 21 2. 从密码派生出加密密钥 22 3. 具体对称加密算法 23 24 **PBES-PKCS12** 25 * pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} 26 * pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} 27 * pbewithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} 28 29 不同于**PKCS#5 v1.5**中的**PBES1**,上述这些是**PKCS#12**的独有算法,特别是它的**KDF**和**密码处理**。 30 31 **PBES1** 32 PBES1属于老旧遗留算法,目前版本未实现。 33 34 **PBES2** 35 由两部分组成,分别为**KDF**和加密算法。目前KDF只支持**KDF2**, KDF2中支持的**PRF**方法有: 36 * id-hmacWithSHA1 37 * id-hmacWithSHA256 38 * id-hmacWithSM3 39 40 具体可参考[PKCS #5: Password-Based Cryptography Specification Version 2.1](https://datatracker.ietf.org/doc/html/rfc8018) 41 42 加密算法有: 43 * AES-CBC-Pad,密钥长度支持16/24/32字节 44 * SM4-CBC-Pad,密钥长度支持16字节 45 46 #### 数据完整性保护(PBMAC) 47 这里只支持基于密码的完整性保护:**PKCS12-KDF + HMAC**。支持的HASH算法有: 48 * SHA1 49 * SHA256 50 * SM3 51 52 **PBMAC**目前的实现还是基于**PKCS12-KDF**,将来看情况是否要实现**PBMAC1**,主要看**OpenSSL**的支持进度: 53 * [Support FIPS-compliant PKCS#12 files and create them by default in FIPS mode](https://github.com/openssl/openssl/issues/24546) 54 * [RFC 9579 implementation: add PBMAC1 with PBKDF2 to PKCS#12](https://github.com/openssl/openssl/pull/24577) 55 56 从**v0.4.1**开始支持**PBMAC1**。 57 58 ## PKCS#12的生成 59 目前只支持下列几种,不支持自由定义: 60 61 * ```LegacyRC2```,加密使用PKCS12特有算法;对证书使用RC2加密,对私钥使用3DES加密,一致性保证使用HMAC-SHA1。 62 * ```LegacyDES```,加密使用PKCS12特有算法;对证书和私钥都是用3DES加密,一致性保证使用HMAC-SHA1。 63 * ```Passwordless```,无加密、一致性保证模式。 64 * ```Modern2023```,对应OpenSSL 3+ 默认,加密使用AES-256-CBC with PBKDF2,一致性保证使用HMAC-SHA256。 65 * ```ShangMi2024```,这个估计目前没什么互操作性。 66 67 目前的全局函数```Encode``` / ```EncodeTrustStore```使用**LegacyRC2**编码器。 68 69 ```go 70 // LegacyRC2 encodes PKCS#12 files using weak algorithms that were 71 // traditionally used in PKCS#12 files, including those produced 72 // by OpenSSL before 3.0.0, go-pkcs12 before 0.3.0, and Java when 73 // keystore.pkcs12.legacy is defined. Specifically, certificates 74 // are encrypted using PBE with RC2, and keys are encrypted using PBE 75 // with 3DES, using keys derived with 2048 iterations of HMAC-SHA-1. 76 // MACs use HMAC-SHA-1 with keys derived with 1 iteration of HMAC-SHA-1. 77 // 78 // Due to the weak encryption, it is STRONGLY RECOMMENDED that you use [DefaultPassword] 79 // when encoding PKCS#12 files using this encoder, and protect the PKCS#12 files 80 // using other means. 81 // 82 // By default, OpenSSL 3 can't decode PKCS#12 files created using this encoder. 83 // For better compatibility, use [LegacyDES]. For better security, use 84 // [Modern2023]. 85 var LegacyRC2 = &Encoder{ 86 macAlgorithm: oidSHA1, 87 certAlgorithm: oidPBEWithSHAAnd40BitRC2CBC, 88 keyAlgorithm: oidPBEWithSHAAnd3KeyTripleDESCBC, 89 kdfPrf: nil, 90 encryptionScheme: nil, 91 macIterations: 1, 92 encryptionIterations: 2048, 93 saltLen: 8, 94 rand: rand.Reader, 95 } 96 97 // LegacyDES encodes PKCS#12 files using weak algorithms that are 98 // supported by a wide variety of software. Certificates and keys 99 // are encrypted using PBE with 3DES using keys derived with 2048 100 // iterations of HMAC-SHA-1. MACs use HMAC-SHA-1 with keys derived 101 // with 1 iteration of HMAC-SHA-1. These are the same parameters 102 // used by OpenSSL's -descert option. As of 2023, this encoder is 103 // likely to produce files that can be read by the most software. 104 // 105 // Due to the weak encryption, it is STRONGLY RECOMMENDED that you use [DefaultPassword] 106 // when encoding PKCS#12 files using this encoder, and protect the PKCS#12 files 107 // using other means. To create more secure PKCS#12 files, use [Modern2023]. 108 var LegacyDES = &Encoder{ 109 macAlgorithm: oidSHA1, 110 certAlgorithm: oidPBEWithSHAAnd3KeyTripleDESCBC, 111 keyAlgorithm: oidPBEWithSHAAnd3KeyTripleDESCBC, 112 kdfPrf: nil, 113 encryptionScheme: nil, 114 macIterations: 1, 115 encryptionIterations: 2048, 116 saltLen: 8, 117 rand: rand.Reader, 118 } 119 120 // Passwordless encodes PKCS#12 files without any encryption or MACs. 121 // A lot of software has trouble reading such files, so it's probably only 122 // useful for creating Java trust stores using [Encoder.EncodeTrustStore] 123 // or [Encoder.EncodeTrustStoreEntries]. 124 // 125 // When using this encoder, you MUST specify an empty password. 126 var Passwordless = &Encoder{ 127 macAlgorithm: nil, 128 certAlgorithm: nil, 129 keyAlgorithm: nil, 130 kdfPrf: nil, 131 encryptionScheme: nil, 132 rand: rand.Reader, 133 } 134 135 // Modern2023 encodes PKCS#12 files using algorithms that are considered modern 136 // as of 2023. Private keys and certificates are encrypted using PBES2 with 137 // PBKDF2-HMAC-SHA-256 and AES-256-CBC. The MAC algorithm is HMAC-SHA-2. These 138 // are the same algorithms used by OpenSSL 3 (by default), Java 20 (by default), 139 // and Windows Server 2019 (when "stronger" is used). 140 // 141 // Files produced with this encoder can be read by OpenSSL 1.1.1 and higher, 142 // Java 12 and higher, and Windows Server 2019 and higher. 143 // 144 // For passwords, it is RECOMMENDED that you do one of the following: 145 // 1) Use [DefaultPassword] and protect the file using other means, or 146 // 2) Use a high-entropy password, such as one generated with `openssl rand -hex 16`. 147 // 148 // You SHOULD NOT use a lower-entropy password with this encoder because the number of KDF 149 // iterations is only 2048 and doesn't provide meaningful protection against 150 // brute-forcing. You can increase the number of iterations using [Encoder.WithIterations], 151 // but as https://neilmadden.blog/2023/01/09/on-pbkdf2-iterations/ explains, this doesn't 152 // help as much as you think. 153 var Modern2023 = &Encoder{ 154 macAlgorithm: oidSHA256, 155 certAlgorithm: oidPBES2, 156 keyAlgorithm: oidPBES2, 157 kdfPrf: oidHmacWithSHA256, 158 encryptionScheme: oidAES256CBC, 159 macIterations: 2048, 160 encryptionIterations: 2048, 161 saltLen: 16, 162 rand: rand.Reader, 163 } 164 165 // ShangMi2024 encodes PKCS#12 files using algorithms that are all ShangMi. 166 // Private keys and certificates are encrypted using PBES2 with PBKDF2-HMAC-SM3 and SM4-CBC. 167 // The MAC algorithm is PBMAC1-HMAC-SM3. 168 var ShangMi2024 = &Encoder{ 169 macAlgorithm: oidPBMAC1, 170 certAlgorithm: oidPBES2, 171 keyAlgorithm: oidPBES2, 172 kdfPrf: oidHmacWithSM3, 173 encryptionScheme: oidSM4CBC, 174 messageAuthScheme: oidHmacWithSM3, 175 macIterations: 2048, 176 encryptionIterations: 2048, 177 saltLen: 16, 178 rand: rand.Reader, 179 } 180 ``` 181 182 ## 解析加密的PKCS#8私钥 183 [go-pkcs12](https://github.com/emmansun/go-pkcs12) 也提供了```ParsePKCS8PrivateKey```方法,相比**pkcs8**的类似方法,这里特别支持**PBES-PKCS12**加密算法。 184 * PBE-SHA1-RC2-128 185 * PBE-SHA1-RC2-40 186 * PBE-SHA1-3DES