• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 证书开发指导
2
3> **说明**
4>
5> 本开发指导基于API version 9,OH SDK版本3.2.9及以上,适用于JS语言开发
6
7## 使用证书操作
8
9**场景说明**
10
11使用证书操作中,典型的场景有:
12
131. 解析X509证书数据生成证书对象。
142. 获取证书信息,比如:证书版本、证书序列号等。
153. 获取证书对象的序列化数据。
164. 获取证书公钥。
175. 证书验签。
186. 校验证书有效期。
19
20**接口及参数说明**
21
22详细接口说明可参考[API参考](../reference/apis/js-apis-cert.md)。
23
24以上场景涉及的常用接口如下表所示:
25
26| 实例名          | 接口名                                                       | 描述                                         |
27| --------------- | ------------------------------------------------------------ | -------------------------------------------- |
28| cryptoCert | createX509Cert(inStream : EncodingBlob, callback : AsyncCallback\<X509Cert>) : void | 使用callback方式解析X509证书数据生成证书对象 |
29| cryptoCert | createX509Cert(inStream : EncodingBlob) : Promise\<X509Cert>  | 使用promise方式解析X509证书数据生成证书对象  |
30| X509Cert        | verify(key : cryptoFramework.PubKey, callback : AsyncCallback\<void>) : void  | 使用callback方式进行证书验签                 |
31| X509Cert        | verify(key : cryptoFramework.PubKey) : Promise\<void>                         | 使用promise方式进行证书验签                  |
32| X509Cert        | getEncoded(callback : AsyncCallback\<EncodingBlob>) : void    | 使用callback方式获取证书序列化数据           |
33| X509Cert        | getEncoded() : Promise\<EncodingBlob>                         | 使用promise方式获取证书序列化数据            |
34| X509Cert        | getPublicKey() : cryptoFramework.PubKey                       | 获取证书公钥                               |
35| X509Cert        | checkValidityWithDate(date: string) : void                   | 校验证书有效期                              |
36| X509Cert        | getVersion() : number                                        | 获取证书版本                                 |
37| X509Cert        | getSerialNumber() : number                                   | 获取证书序列号                               |
38| X509Cert        | getIssuerName() : DataBlob                                   | 获取证书颁发者名称                           |
39| X509Cert        | getSubjectName() : DataBlob                                  | 获取证书主体名称                             |
40| X509Cert        | getNotBeforeTime() : string                                  | 获取证书有效期起始时间                       |
41| X509Cert        | getNotAfterTime() : string                                   | 获取证书有效期截至时间                       |
42| X509Cert        | getSignature() : DataBlob                                    | 获取证书签名                                 |
43| X509Cert        | getSignatureAlgName() : string                               | 获取证书签名算法名称                         |
44| X509Cert        | getSignatureAlgOid() : string                                | 获取证书签名算法OID                          |
45| X509Cert        | getSignatureAlgParams() : DataBlob                           | 获取证书签名算法参数                         |
46| X509Cert        | getKeyUsage() : DataBlob                                     | 获取证书秘钥用途                             |
47| X509Cert        | getExtKeyUsage() : DataArray                                 | 获取证书扩展秘钥用途                         |
48| X509Cert        | getBasicConstraints() : number                               | 获取证书基本约束                             |
49| X509Cert        | getSubjectAltNames() : DataArray                             | 获取证书主体可选名称                         |
50| X509Cert        | getIssuerAltNames() : DataArray                              | 获取证书颁发者可选名称                       |
51
52**开发步骤**
53
54示例:解析X509证书数据生成证书对象,并调用对象方法(包含场景1-6)
55
56```javascript
57import cryptoCert from '@ohos.security.cert';
58import cryptoFramework from '@ohos.security.cryptoFramework';
59
60// 证书数据,此处仅示例,业务需根据场景自行设置
61let certData = "-----BEGIN CERTIFICATE-----\n"
62+ "IBzTCCAXCgAwIBAgIGAXKnMKNyMAwGCCqBHM9VAYN1BQAwSTELMAkGA1UEBhMC\n"
63+ "04xDjAMBgNVBAoTBUdNU1NMMRAwDgYDVQQLEwdQS0kvU00yMRgwFgYDVQQDEw9S\n"
64+ "290Q0EgZm9yIFRlc3QwIhgPMjAxNTEyMzExNjAwMDBaGA8yMDM1MTIzMDE2MDAw\n"
65+ "FowSTELMAkGA1UEBhMCQ04xDjAMBgNVBAoTBUdNU1NMMRAwDgYDVQQLEwdQS0kv\n"
66+ "00yMRgwFgYDVQQDEw9Sb290Q0EgZm9yIFRlc3QwWTATBgcqhkjOPQIBBggqgRzP\n"
67+ "QGCLQNCAATj+apYlL+ddWXZ7+mFZXZJGbcJFXUN+Fszz6humeyWZP4qEEr2N0+a\n"
68+ "dwo/21ft232yo0jPLzdscKB261zSQXSoz4wPDAZBgNVHQ4EEgQQnGnsD7oaOcWv\n"
69+ "CTrspwSBDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIAxjAMBggqgRzP\n"
70+ "QGDdQUAA0kAMEYCIQCEnW5BlQh0vmsOLxSoXYc/7zs++wWyFc1tnBHENR4ElwIh\n"
71+ "I1Lwu6in1ruflZhzseWulXwcITf3bm/Y5X1g1XFWQUH\n"
72+ "-----END CERTIFICATE-----\n";
73
74// string转Uint8Array
75function stringToUint8Array(str) {
76    var arr = [];
77    for (var i = 0, j = str.length; i < j; i++) {
78        arr.push(str.charCodeAt(i));
79    }
80    return new Uint8Array(arr);
81}
82
83// 证书示例
84function certSample() {
85    let encodingBlob = {
86        // 将string类型证书数据转为Uint8Array
87        data: stringToUint8Array(certData),
88        // 证书格式:支持PEM和DER,此例中对应PEM
89        encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM
90    };
91
92    // 创建证书对象
93    cryptoCert.createX509Cert(encodingBlob, function (err, x509Cert) {
94        if (err != null) {
95            // 创建证书对象失败
96            console.log("createX509Cert failed, errCode: " + err.code + ", errMsg: " + err.message);
97            return;
98        }
99        // 创建证书对象成功
100        console.log("createX509Cert success");
101
102        // 获取证书版本
103        let version = x509Cert.getVersion();
104
105        // 获取证书对象的序列化数据
106        x509Cert.getEncoded(function (err, data) {
107            if (err != null) {
108                // 获取序列化数据失败
109                console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message);
110            } else {
111                // 获取序列化数据成功
112                console.log("getEncoded success");
113            }
114        });
115
116        // 业务需通过上级证书对象或本证书对象(自签名)的getPublicKey接口获取公钥对象,此处省略
117        let pubKey = null;
118        try {
119            pubKey = x509Cert.getPublicKey();
120        } catch (error) {
121            console.log("getPublicKey failed, errCode: " + error.code + ", errMsg: " + error.message);
122        }
123
124        // 证书验签
125        x509Cert.verify(pubKey, function (err, data) {
126            if (err == null) {
127                // 验签成功
128                console.log("verify success");
129            } else {
130                // 验签失败
131                console.log("verify failed, errCode: " + err.code + ", errMsg: " + err.message);
132            }
133        });
134
135        // 时间字符串
136        let date = "150527000001Z";
137
138        // 校验证书有效期
139        try {
140            x509Cert.checkValidityWithDate(date);
141        } catch (error) {
142            console.log("checkValidityWithDate failed, errCode: " + error.code + ", errMsg: " + error.message);
143        }
144    });
145}
146```
147
148## 使用证书吊销列表操作
149
150**场景说明**
151
152使用证书吊销列表操作中,典型的场景有:
153
1541. 解析X509证书吊销列表数据生成吊销列表对象。
1552. 获取证书吊销列表信息,比如:证书吊销列表版本、证书吊销列表类型等。
1563. 获取证书吊销列表对象的序列化数据。
1574. 检查证书是否被吊销。
1585. 证书吊销列表验签。
1596. 获取被吊销证书。
160
161**接口及参数说明**
162
163详细接口说明可参考[API参考](../reference/apis/js-apis-cert.md)。
164
165以上场景涉及的常用接口如下表所示:
166
167| 实例名          | 接口名                                                       | 描述                                                         |
168| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
169| cryptoCert | createX509Crl(inStream : EncodingBlob, callback : AsyncCallback\<X509Crl>) : void | 使用callback方式解析X509证书吊销列表数据生成证书吊销列表对象 |
170| cryptoCert | createX509Crl(inStream : EncodingBlob) : Promise\<X509Crl>    | 使用promise方式解析X509证书吊销列表数据生成证书吊销列表对象  |
171| X509Crl         | isRevoked(cert : X509Cert) : boolean                     |  检查证书是否被吊销                            |
172| X509Crl         | getType() : string                                           | 获取证书吊销列表类型                                        |
173| X509Crl         | getEncoded(callback : AsyncCallback\<EncodingBlob>) : void    | 使用callback方式获取证书吊销列表序列化数据                   |
174| X509Crl         | getEncoded() : Promise\<EncodingBlob>                         | 使用promise方式获取证书吊销列表序列化数据                    |
175| X509Crl         | verify(key : cryptoFramework.PubKey, callback : AsyncCallback\<void>) : void  | 使用callback方式进行证书吊销列表验签        |
176| X509Crl         | verify(key : cryptoFramework.PubKey) : Promise\<void>                         | 使用Promise方式进行证书吊销列表验签         |
177| X509Crl         | getVersion() : number                                        | 获取证书吊销列表版本                                        |
178| X509Crl         | getIssuerName() : DataBlob                                   | 获取证书吊销列表颁发者名称                                   |
179| X509Crl         | getLastUpdate() : string                                     | 获取证书吊销列表lastUpdate日期                               |
180| X509Crl         | getNextUpdate() : string                                     | 获取证书吊销列表nextUpdate日期                               |
181| X509Crl         | getRevokedCert(serialNumber : number) : X509CrlEntry         | 通过序列号获取证书吊销列表中的被吊销证书                       |
182| X509Crl         | getRevokedCertWithCert(cert : X509Cert) : X509CrlEntry         | 通过X509证书获取证书吊销列表中的被吊销证书                   |
183| X509Crl         | getRevokedCerts(callback : AsyncCallback\<Array\<X509CrlEntry>>) : void | 使用callback方式获取证书吊销列表的所有被吊销证书    |
184| X509Crl         | getRevokedCerts() : Promise\<Array\<X509CrlEntry>>             | 使用Promise方式获取证书吊销列表的所有被吊销证书              |
185| X509Crl         | getTbsInfo() : DataBlob                                      | 获取证书吊销列表的tbsCertList                                |
186| X509Crl         | getSignature() : DataBlob                                    | 获取证书吊销列表的签名                                       |
187| X509Crl         | getSignatureAlgName() : string                               | 获取证书吊销列表的签名算法名称                                |
188| X509Crl         | getSignatureAlgOid() : string                                | 获取证书吊销列表的签名算法OID                                 |
189| X509Crl         | getSignatureAlgParams() : DataBlob                           | 获取证书吊销列表的签名算法参数                                |
190
191**开发步骤**
192
193示例:解析X509证书吊销列表数据生成证书吊销列表对象,并调用对象方法(包含场景1-6)
194
195```javascript
196import cryptoCert from '@ohos.security.cert';
197import cryptoFramework from '@ohos.security.cryptoFramework';
198
199// 证书吊销列表数据,此处仅示例,业务需根据场景自行设置
200let crlData = "-----BEGIN X509 CRL-----\n"
201+ "MIIBijB0AgEBMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCHJvb3QtY2ExFw0y\n"
202+ "MDA2MTkxNjE1NDhaFw0yMDA3MTkxNjE1NDhaMBwwGgIJAMsozRATnap1Fw0yMDA2\n"
203+ "MTkxNjEyMDdaoA8wDTALBgNVHRQEBAICEAIwDQYJKoZIhvcNAQELBQADggEBACPs\n"
204+ "9gQB+djaXPHHRmAItebZpD3iJ/e36Dxr6aMVkn9FkI8OVpUI4RNcCrywyCZHQJte\n"
205+ "995bbPjP7f1sZstOTZS0fDPgJ5SPAxkKOQB+SQnBFrlZSsxoUNU60gRqd2imR0Rn\n"
206+ "1r09rP69F6E4yPc9biEld+llLGgoImP3zPOVDD6fbfcvVkjStY3bssVEQ/vjp4a3\n"
207+ "/I12U7ZnSe3jaKqaQBoVJppkTFOIOq7IOxf5/IkMPmvRHDeC2IzDMzcUxym0dkny\n"
208+ "EowHrjzo0bZVqpHMA2YgKZuwTpVLHk9GeBEK2hVkIoPVISkmiU4HFg0S6z68C5yd\n"
209+ "DrAA7hErVgXhtURLbAI=\n"
210+ "-----END X509 CRL-----\n";
211
212// string转Uint8Array
213function stringToUint8Array(str) {
214    var arr = [];
215    for (var i = 0, j = str.length; i < j; i++) {
216        arr.push(str.charCodeAt(i));
217    }
218    return new Uint8Array(arr);
219}
220
221// 证书吊销列表示例
222function crlSample() {
223    let encodingBlob = {
224        // 将string类型证书吊销列表数据转为Uint8Array
225        data: stringToUint8Array(crlData),
226        // 证书吊销列表格式:支持PEM和DER,此例中对应PEM
227        encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM
228    };
229
230    // 创建证书吊销列表对象
231    cryptoCert.createX509Crl(encodingBlob, function (err, x509Crl) {
232        if (err != null) {
233            // 创建证书吊销列表对象失败
234            console.log("createX509Crl failed, errCode: " + err.code + ", errMsg: " + err.message);
235            return;
236        }
237        // 创建证书吊销列表对象成功
238        console.log("createX509Crl success");
239
240        // 获取证书吊销列表版本
241        let version = x509Crl.getVersion();
242
243        // 获取证书吊销列表对象的序列化数据
244        x509Crl.getEncoded(function (err, data) {
245            if (err != null) {
246                // 获取序列化数据失败
247                console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message);
248            } else {
249                // 获取序列化数据成功
250                console.log("getEncoded success");
251            }
252        });
253
254        // 业务需通过cryptoFramework的createX509Cert生成X509Cert证书对象,此处省略
255        let x509Cert = null;
256        // 检查证书是否被吊销
257        try {
258            let revokedFlag = x509Crl.isRevoked(x509Cert);
259        } catch (error) {
260           console.log("isRevoked failed, errCode: " + error.code + ", errMsg: " + error.message);
261        }
262
263        // 业务需通过将public key二进制数据输入 @ohos.security.cryptoFramework的convertKey接口获取PubKey对象,此处省略
264        let pubKey = null;
265
266        // 证书吊销列表验签
267        x509Crl.verify(pubKey, function (err, data) {
268            if (err == null) {
269                // 验签成功
270                console.log("verify success");
271            } else {
272                // 验签失败
273                console.log("verify failed, errCode: " + err.code + ", errMsg: " + err.message);
274            }
275        });
276
277        // 证书序列号,业务需自行设置
278        let serialNumber = 1000;
279
280        // 获取被吊销证书对象
281        try {
282            let entry = x509Crl.getRevokedCert(serialNumber);
283        } catch (error) {
284           console.log("getRevokedCert failed, errCode: " + error.code + ", errMsg: " + error.message);
285        }
286    });
287}
288```
289
290## 使用证书链校验器操作
291
292**场景说明**
293
294使用证书链校验器操作中,典型的场景:证书链校验。
295
296**接口及参数说明**
297
298详细接口说明可参考[API参考](../reference/apis/js-apis-cert.md)。
299
300以上场景涉及的常用接口如下表所示:
301
302| 实例名             | 接口名                                                       | 描述                             |
303| ------------------ | ------------------------------------------------------------ | -------------------------------- |
304| cryptoCert | createCertChainValidator(algorithm :string) : CertChainValidator | 使用指定算法生成证书链校验器对象 |
305| CertChainValidator | validate(certChain : CertChainData, callback : AsyncCallback\<void>) : void | 使用callback方式校验证书链   |
306| CertChainValidator | validate(certChain : CertChainData) : Promise\<void>          | 使用promise方式校验证书链        |
307| CertChainValidator | algorithm : string                                           | 证书链校验器算法名称             |
308
309**开发步骤**
310
311示例:创建证书链校验器对象,并对证书链数据进行校验(场景1)
312
313```javascript
314import cryptoCert from '@ohos.security.cert';
315
316// 一级证书数据,此处仅示例,业务需自行设置真实数据
317let caCertData = "-----BEGIN CERTIFICATE-----\n"
318+ "...\n"
319+ "...\n"
320+ "...\n"
321+ "-----END CERTIFICATE-----\n";
322
323// 二级证书数据,此处仅示例,业务需自行设置真实数据
324let secondCaCertData = "-----BEGIN CERTIFICATE-----\n"
325+ "...\n"
326+ "...\n"
327+ "...\n"
328+ "-----END CERTIFICATE-----\n";
329
330// string转Uint8Array
331function stringToUint8Array(str) {
332    var arr = [];
333    for (var i = 0, j = str.length; i < j; i++) {
334        arr.push(str.charCodeAt(i));
335    }
336    return new Uint8Array(arr);
337}
338
339// 证书链校验器示例:此示例中以校验二级证书链为例,业务需根据场景自行修改
340function certChainValidatorSample() {
341    // 证书链校验器算法,当前仅支持PKIX
342    let algorithm = "PKIX";
343
344    // 创建证书链校验器对象
345    let validator = cryptoCert.createCertChainValidator(algorithm);
346
347    // 一级证书数据
348    let uint8ArrayOfCaCertData = stringToUint8Array(caCertData);
349
350    // 一级证书数据长度
351    let uint8ArrayOfCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOfCaCertData.byteLength]).buffer);
352
353    // 二级证书数据
354    let uint8ArrayOf2ndCaCertData = stringToUint8Array(secondCaCertData);
355
356    // 二级证书数据长度
357    let uint8ArrayOf2ndCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOf2ndCaCertData.byteLength]).buffer);
358
359    // 证书链二进制数据:二级证书数据长度+二级证书数据+一级证书数据长度+一级证书数据(L-V格式)
360    let encodingData = new Uint8Array(uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length +
361                                     uint8ArrayOfCaCertDataLen.length + uint8ArrayOfCaCertData.length);
362    for (var i = 0; i < uint8ArrayOf2ndCaCertDataLen.length; i++) {
363        encodingData[i] = uint8ArrayOf2ndCaCertDataLen[i];
364    }
365    for (var i = 0; i < uint8ArrayOf2ndCaCertData.length; i++) {
366        encodingData[uint8ArrayOf2ndCaCertDataLen.length + i] = uint8ArrayOf2ndCaCertData[i];
367    }
368    for (var i = 0; i < uint8ArrayOfCaCertDataLen.length; i++) {
369        encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + i] = uint8ArrayOfCaCertDataLen[i];
370    }
371    for (var i = 0; i < uint8ArrayOfCaCertData.length; i++) {
372        encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length +
373                     uint8ArrayOfCaCertDataLen.length + i] = uint8ArrayOfCaCertData[i];
374    }
375
376    let certChainData = {
377        // Uint8Array类型:L-V格式(证书数据长度-证书数据)
378        data: encodingData,
379        // 证书数量,此示例中为2
380        count: 2,
381        // 证书格式:支持PEM和DER,此例中对应PEM
382        encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM
383    };
384
385    // 校验证书链
386    validator.validate(certChainData, function (err, data) {
387        if (err != null) {
388            // 证书链校验失败
389            console.log("validate failed, errCode: " + err.code + ", errMsg: " + err.message);
390        } else {
391            // 证书链校验成功
392            console.log("validate success");
393        }
394	});
395}
396```
397
398## 使用被吊销证书操作
399
400**场景说明**
401
402使用被吊销证书操作中,典型的场景有:
403
4041. 获取被吊销证书对象。
4052. 获取被吊销证书信息,比如:序列号、证书颁发者、证书吊销日期。
4063. 获取被吊销证书对象的序列化数据。
407
408**接口及参数说明**
409
410详细接口说明可参考[API参考](../reference/apis/js-apis-cert.md)。
411
412以上场景涉及的常用接口如下表所示:
413
414| 实例名       | 接口名                                                      | 描述                                      |
415| ------------ | ----------------------------------------------------------- | ---------------------------------------- |
416| X509CrlEntry | getEncoded(callback : AsyncCallback\<EncodingBlob>) : void;  | 使用callback方式获取被吊销证书的序列化数据 |
417| X509CrlEntry | getEncoded() : Promise\<EncodingBlob>;                       | 使用promise方式获取被吊销证书的序列化数据  |
418| X509CrlEntry | getSerialNumber() : number;                                  | 获取被吊销证书的序列号                    |
419| X509CrlEntry | getCertIssuer() : DataBlob;                                  | 获取被吊销证书颁发者                     |
420| X509CrlEntry | getRevocationDate() : string;                                | 获取被吊销证书的吊销日期                  |
421
422**开发步骤**
423
424示例:获取被吊销证书对象,并调用对象方法(包含场景1-3)
425
426```javascript
427import cryptoCert from '@ohos.security.cert';
428
429// 被吊销证书示例
430function crlEntrySample() {
431    // 业务需自行通过cryptoFramework的createX509Crl接口创建X509Crl对象,此处省略
432    let x509Crl = null;
433
434    // 获取被吊销证书对象,业务需根据场景调用X509Crl的接口获取,此示例使用getRevokedCert获取
435    let serialNumber = 1000;
436    let crlEntry = null;
437    try {
438        crlEntry = x509Crl.getRevokedCert(serialNumber);
439    } catch (error) {
440        console.log("getRevokedCert failed, errCode: " + error.code + ", errMsg: " + error.message);
441    }
442
443    // 获取被吊销证书的序列号
444    serialNumber = crlEntry.getSerialNumber();
445
446    // 获取被吊销证书的吊销日期
447    try {
448        crlEntry.getRevocationDate();
449    } catch (error) {
450        console.log("getRevocationDate failed, errCode: " + error.code + ", errMsg: " + error.message);
451    }
452
453    // 获取被吊销证书对象的序列化数据
454    crlEntry.getEncoded(function (err, data) {
455        if (err != null) {
456            // 获取序列化数据失败
457            console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message);
458        } else {
459            // 获取序列化数据成功
460            console.log("getEncoded success");
461        }
462    });
463}
464```
465