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