• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Certificate Development
2
3> **NOTE**
4>
5> This development guide applies to API version 9, OpenHarmony SDK version 3.2.9 or later, and JS development.
6
7## Using Certificates
8
9**When to Use**
10
11Typical operations involve the following:
12
131. Parse X.509 certificate data to generate a certificate object.
142. Obtain certificate information, such as the version and serial number of the certificate.
153. Obtains the serialized data of the certificate object.
164. Obtain the certificate public key.
175. Verify the certificate signature.
186. Verify the certificate validity period.
19
20**Available APIs**
21
22For details about the APIs, see [Certificate](../reference/apis/js-apis-cert.md).
23
24The table below describes the APIs used in this guide.
25
26| Instance         | API                                                      | Description                                        |
27| --------------- | ------------------------------------------------------------ | -------------------------------------------- |
28| cryptoCert | createX509Cert(inStream : EncodingBlob, callback : AsyncCallback\<X509Cert>) : void | Parses certificate data to create an **X509Cert** instance. This API uses an asynchronous callback to return the result.|
29| cryptoCert | createX509Cert(inStream : EncodingBlob) : Promise\<X509Cert>  | Parses certificate data to create an **X509Cert** instance. This API uses a promise to return the result. |
30| X509Cert        | verify(key : cryptoFramework.PubKey, callback : AsyncCallback\<void>) : void  | Verifies the certificate signature. This API uses an asynchronous callback to return the result.                |
31| X509Cert        | verify(key : cryptoFramework.PubKey) : Promise\<void>                         | Verifies the certificate signature. This API uses a promise to return the result.                 |
32| X509Cert        | getEncoded(callback : AsyncCallback\<EncodingBlob>) : void    | Obtains serialized certificate data. This API uses an asynchronous callback to return the result.          |
33| X509Cert        | getEncoded() : Promise\<EncodingBlob>                         | Obtains serialized certificate data. This API uses a promise to return the result.           |
34| X509Cert        | getPublicKey() : cryptoFramework.PubKey                       | Obtains the certificate public key.                              |
35| X509Cert        | checkValidityWithDate(date: string) : void                   | Checks the certificate validity period.                             |
36| X509Cert        | getVersion() : number                                        | Obtains the certificate version.                                |
37| X509Cert        | getSerialNumber() : number                                   | Obtains the certificate serial number.                              |
38| X509Cert        | getIssuerName() : DataBlob                                   | Obtains the certificate issuer.                          |
39| X509Cert        | getSubjectName() : DataBlob                                  | Obtains the certificate subject.                            |
40| X509Cert        | getNotBeforeTime() : string                                  | Obtains the time from which the certificate takes effect.                      |
41| X509Cert        | getNotAfterTime() : string                                   | Obtains the expiration time of the certificate.                      |
42| X509Cert        | getSignature() : DataBlob                                    | Obtains the certificate signature.                                |
43| X509Cert        | getSignatureAlgName() : string                               | Obtain the certificate signing algorithm.                        |
44| X509Cert        | getSignatureAlgOid() : string                                | Obtains the certificate signing algorithm object identifier (OID).                         |
45| X509Cert        | getSignatureAlgParams() : DataBlob                           | Obtains the certificate signing algorithm parameters.                        |
46| X509Cert        | getKeyUsage() : DataBlob                                     | Obtains the key usage of the certificate.                            |
47| X509Cert        | getExtKeyUsage() : DataArray                                 | Obtains the usage of the certificate extension key.                        |
48| X509Cert        | getBasicConstraints() : number                               | Obtains the basic constraints on the certificate.                            |
49| X509Cert        | getSubjectAltNames() : DataArray                             | Obtains the Subject Alternative Names (SANs) of the certificate.                        |
50| X509Cert        | getIssuerAltNames() : DataArray                              | Obtains the Issuer Alternative Names (IANs) of the certificate.                      |
51
52**How to Develop**
53
54Example: Parse the X.509 certificate data to create an **X509Cert** instance and call APIs to perform certificate operations.
55
56```javascript
57import cryptoCert from '@ohos.security.cert';
58import cryptoFramework from '@ohos.security.cryptoFramework';
59
60// Certificate data, which is only an example. The certificate data varies with the service.
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// Convert the certificate data form a string to a 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// Certificate example
84function certSample() {
85    let encodingBlob = {
86        // Convert the certificate data string to a Uint8Array.
87        data: stringToUint8Array(certData),
88        // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format.
89        encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM
90    };
91
92    // Create an X509Cert instance.
93    cryptoCert.createX509Cert(encodingBlob, function (err, x509Cert) {
94        if (err != null) {
95            // Failed to create the X509Cert instance.
96            console.log("createX509Cert failed, errCode: " + err.code + ", errMsg: " + err.message);
97            return;
98        }
99        // The X509Cert instance is successfully created.
100        console.log("createX509Cert success");
101
102        // Obtain the certificate version.
103        let version = x509Cert.getVersion();
104
105        // Obtain the serialized data of the certificate.
106        x509Cert.getEncoded(function (err, data) {
107            if (err != null) {
108                // Failed to obtain the serialized data of the certificate.
109                console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message);
110            } else {
111                // The serialized data of the certificate is successfully obtained.
112                console.log("getEncoded success");
113            }
114        });
115
116        // Obtain the public key object using the getPublicKey() of the upper-level certificate object or this (self-signed) certificate object.
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        // Verify the certificate signature.
125        x509Cert.verify(pubKey, function (err, data) {
126            if (err == null) {
127                // The signature verification is successful.
128                console.log("verify success");
129            } else {
130                // The signature verification failed.
131                console.log("verify failed, errCode: " + err.code + ", errMsg: " + err.message);
132            }
133        });
134
135        // Time represented in a string.
136        let date = "150527000001Z";
137
138        // Verify the certificate validity period.
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## Using the CRL
149
150**When to Use**
151
152Typical operations involve the following:
153
1541. Parse the X.509 CRL data to create an **X509Crl** instance.
1552. Obtain the CRL information, such as the CRL version and type.
1563. Obtain the serialized data of the CRL.
1574. Check whether the certificate is revoked.
1585. Verify the CRL signature.
1596. Obtain the revoked certificates.
160
161**Available APIs**
162
163For details about the APIs, see [Certificate](../reference/apis/js-apis-cert.md).
164
165The table below describes the APIs used in this guide.
166
167| Instance         | API                                                      | Description                                                        |
168| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
169| cryptoCert | createX509Crl(inStream : EncodingBlob, callback : AsyncCallback\<X509Crl>) : void | Parses the X.509 CRL data to create an **X509Crl** instance. This API uses an asynchronous callback to return the result.|
170| cryptoCert | createX509Crl(inStream : EncodingBlob) : Promise\<X509Crl>    | Parses the X.509 CRL data to create an **X509Crl** instance. This API uses a promise to return the result. |
171| X509Crl         | isRevoked(cert : X509Cert) : boolean                     |  Checks whether the certificate is revoked.                           |
172| X509Crl         | getType() : string                                           | Obtains the CRL type.                                       |
173| X509Crl         | getEncoded(callback : AsyncCallback\<EncodingBlob>) : void    | Obtains the serialized CRL data. This API uses an asynchronous callback to return the result.                  |
174| X509Crl         | getEncoded() : Promise\<EncodingBlob>                         | Obtains the serialized CRL data. This API uses a promise to return the result.                   |
175| X509Crl         | verify(key : cryptoFramework.PubKey, callback : AsyncCallback\<void>) : void  | Verifies the CRL signature. This API uses an asynchronous callback to return the result.       |
176| X509Crl         | verify(key : cryptoFramework.PubKey) : Promise\<void>                         | Verifies the CRL signature. This API uses a promise to return the result.        |
177| X509Crl         | getVersion() : number                                        | Obtains the CRL version.                                       |
178| X509Crl         | getIssuerName() : DataBlob                                   | Obtains the CRL issuer.                                  |
179| X509Crl         | getLastUpdate() : string                                     | Obtains the date when the CRL was last updated.                              |
180| X509Crl         | getNextUpdate() : string                                     | Obtains the next update date of the CRL.                              |
181| X509Crl         | getRevokedCert(serialNumber : number) : X509CrlEntry         | Obtains the revoked certificate in the CRL based on the serial number.                      |
182| X509Crl         | getRevokedCertWithCert(cert : X509Cert) : X509CrlEntry         | Obtains the revoked certificate in the CRL based on the X.509 certificate.                  |
183| X509Crl         | getRevokedCerts(callback : AsyncCallback\<Array\<X509CrlEntry>>) : void | Obtains all revoked certificates in the CRL. This API uses an asynchronous callback to return the result.   |
184| X509Crl         | getRevokedCerts() : Promise\<Array\<X509CrlEntry>>             | Obtains all revoked certificates in the CRL. This API uses a promise to return the result.             |
185| X509Crl         | getTbsInfo() : DataBlob                                      | Obtains **tbsCertList** of the CRL.                               |
186| X509Crl         | getSignature() : DataBlob                                    | Obtains the CRL signature.                                      |
187| X509Crl         | getSignatureAlgName() : string                               | Obtains the CRL signing algorithm.                               |
188| X509Crl         | getSignatureAlgOid() : string                                | Obtains the signing algorithm OID of the CRL.                                |
189| X509Crl         | getSignatureAlgParams() : DataBlob                           | Obtains the signing algorithm parameters of the CRL.                               |
190
191**How to Develop**
192
193Example: Parse the X.509 CRL data to create an **X509Crl** instance and call APIs to perform CRL operations.
194
195```javascript
196import cryptoCert from '@ohos.security.cert';
197import cryptoFramework from '@ohos.security.cryptoFramework';
198
199// CRL data, which is only an example. The CRL data varies with the service.
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// Convert the certificate data form a string to a 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// Example of a CRL.
222function crlSample() {
223    let encodingBlob = {
224        // Convert the CRL data from a string to a Uint8Array.
225        data: stringToUint8Array(crlData),
226        // CRL format. Only PEM and DER are supported. In this example, the CRL is in PEM format.
227        encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM
228    };
229
230    // Create an X509Crl instance.
231    cryptoCert.createX509Crl(encodingBlob, function (err, x509Crl) {
232        if (err != null) {
233            // Failed to create the X509Crl instance.
234            console.log("createX509Crl failed, errCode: " + err.code + ", errMsg: " + err.message);
235            return;
236        }
237        // The X509Crl instance is successfully created.
238        console.log("createX509Crl success");
239
240        // Obtain the CRL version.
241        let version = x509Crl.getVersion();
242
243        // Obtain the serialized data of the CRL.
244        x509Crl.getEncoded(function (err, data) {
245            if (err != null) {
246                // Failed to obtain the serialized data of the certificate.
247                console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message);
248            } else {
249                // The serialized data of the certificate is successfully obtained.
250                console.log("getEncoded success");
251            }
252        });
253
254        // Create an X509Cert instance by using createX509Cert() of cryptoFramework.
255        let x509Cert = null;
256        // Check whether the certificate is revoked.
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        // The binary data of the public key needs to be passed to convertKey() of @ohos.security.cryptoFramework to obtain the PubKey object. The process is omitted here.
264        let pubKey = null;
265
266        // Verify the CRL signature.
267        x509Crl.verify(pubKey, function (err, data) {
268            if (err == null) {
269                // The signature verification is successful.
270                console.log("verify success");
271            } else {
272                // The signature verification failed.
273                console.log("verify failed, errCode: " + err.code + ", errMsg: " + err.message);
274            }
275        });
276
277        // Certificate serial number, which must be set based on the service.
278        let serialNumber = 1000;
279
280        // Obtain the revoked certificate based on the serial number.
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## Verifying Certificate Chains
291
292**When to Use**
293
294You need to use the certificate chain validator in certificate chain verification.
295
296**Available APIs**
297
298For details about the APIs, see [Certificate](../reference/apis/js-apis-cert.md).
299
300The table below describes the APIs used in this guide.
301
302| Instance            | API                                                      | Description                            |
303| ------------------ | ------------------------------------------------------------ | -------------------------------- |
304| cryptoCert | createCertChainValidator(algorithm :string) : CertChainValidator | Creates a **CertChainValidator** instance.|
305| CertChainValidator | validate(certChain : CertChainData, callback : AsyncCallback\<void>) : void | Verifies the certificate chain. This API uses an asynchronous callback to return the result.  |
306| CertChainValidator | validate(certChain : CertChainData) : Promise\<void>          | Verifies the certificate chain. This API uses a promise to return the result.       |
307| CertChainValidator | algorithm : string                                           | Obtains the certificate chain validator algorithm.            |
308
309**How to Develop**
310
311Example: Create a **CertChainValidator** instance and verify the certificate chain.
312
313```javascript
314import cryptoCert from '@ohos.security.cert';
315
316// CA certificate data, which is only an example. The CA certificate data varies with the service.
317let caCertData = "-----BEGIN CERTIFICATE-----\n"
318+ "...\n"
319+ "...\n"
320+ "...\n"
321+ "-----END CERTIFICATE-----\n";
322
323// End-entity certificate data, which is only an example. The certificate data varies with the service.
324let secondCaCertData = "-----BEGIN CERTIFICATE-----\n"
325+ "...\n"
326+ "...\n"
327+ "...\n"
328+ "-----END CERTIFICATE-----\n";
329
330// Convert the certificate data form a string to a 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// Certificate chain validator example. In this example, a two-level certificate chain is verified.
340function certChainValidatorSample() {
341    // Certificate chain validator algorithm. Currently, only PKIX is supported.
342    let algorithm = "PKIX";
343
344    // Create a CertChainValidator instance.
345    let validator = cryptoCert.createCertChainValidator(algorithm);
346
347    // CA certificate data.
348    let uint8ArrayOfCaCertData = stringToUint8Array(caCertData);
349
350    // Length of the CA certificate data.
351    let uint8ArrayOfCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOfCaCertData.byteLength]).buffer);
352
353    // End-entity certificate data.
354    let uint8ArrayOf2ndCaCertData = stringToUint8Array(secondCaCertData);
355
356    // Length of the end-entity certificate data.
357    let uint8ArrayOf2ndCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOf2ndCaCertData.byteLength]).buffer);
358
359    // Certificate chain binary data: end-entity certificate data length + end-entity certificate data + CA certificate data length + CA certificate data (in L-V format).
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 type: L-V format (certificate data length-certificate data)
378        data: encodingData,
379        // Number of certificates. It is 2 in this example.
380        count: 2,
381        // Certificate format. PEM and DER are supported. In this example, the certificate is in PEM format.
382        encodingFormat: cryptoCert.EncodingFormat.FORMAT_PEM
383    };
384
385    // Verify the certificate chain.
386    validator.validate(certChainData, function (err, data) {
387        if (err != null) {
388            // The operation fails.
389            console.log("validate failed, errCode: " + err.code + ", errMsg: " + err.message);
390        } else {
391            // The operation is successful.
392            console.log("validate success");
393        }
394	});
395}
396```
397
398## Managing Revoked Certificates
399
400**When to Use**
401
402Typical operations involve the following:
403
4041. Obtain a revoked certificate instance.
4052. Obtain information, such as the serial number, issuer, and certificate revocation date, of the revoked certificate.
4063. Obtain the serialized data of the revoked certificate.
407
408**Available APIs**
409
410For details about the APIs, see [Certificate](../reference/apis/js-apis-cert.md).
411
412The table below describes the APIs used in this guide.
413
414| Instance      | API                                                     | Description                                     |
415| ------------ | ----------------------------------------------------------- | ---------------------------------------- |
416| X509CrlEntry | getEncoded(callback : AsyncCallback\<EncodingBlob>) : void;  | Obtains the serialized data of the revoked certificate. This API uses an asynchronous callback to return the result.|
417| X509CrlEntry | getEncoded() : Promise\<EncodingBlob>;                       | Obtains the serialized data of the revoked certificate. This API uses a promise to return the result. |
418| X509CrlEntry | getSerialNumber() : number;                                  | Obtains the serial number of the revoked certificate.                   |
419| X509CrlEntry | getCertIssuer() : DataBlob;                                  | Obtains the issuer of the revoked certificate.                    |
420| X509CrlEntry | getRevocationDate() : string;                                | Obtains the revocation date of the revoked certificate.                 |
421
422**How to Develop**
423
424Example: Obtain a revoked certificate instance and call the APIs.
425
426```javascript
427import cryptoCert from '@ohos.security.cert';
428
429// Example of a revoked certificate.
430function crlEntrySample() {
431    // Create an **X509Crl** instance by using createX509Crl() of cryptoFramework.
432    let x509Crl = null;
433
434    // Obtain a revoked certificate instance. In this example, the instance is obtained by using 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    // Obtain the serial number of the revoked certificate.
444    serialNumber = crlEntry.getSerialNumber();
445
446    // Obtain the revocation date of the revoked certificate.
447    try {
448        crlEntry.getRevocationDate();
449    } catch (error) {
450        console.log("getRevocationDate failed, errCode: " + error.code + ", errMsg: " + error.message);
451    }
452
453    // Obtain the serialized data of the revoked certificate instance.
454    crlEntry.getEncoded(function (err, data) {
455        if (err != null) {
456            // Failed to obtain the serialized data of the certificate.
457            console.log("getEncoded failed, errCode: " + err.code + ", errMsg: " + err.message);
458        } else {
459            // The serialized data of the certificate is successfully obtained.
460            console.log("getEncoded success");
461        }
462    });
463}
464```
465