1# Certificate Development 2 3> **NOTE** 4> 5> The SDK of API version 9 or later must be used. 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 | getCertSerialNumber() : bigint<sup>10+</sup> | 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 | Obtains 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| X509Cert | getItem(itemType: CertItemType) : DataBlob<sup>10+</sup> | Obtains the fields of the X.509 certificate. | 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```ts 57import certFramework from '@ohos.security.cert'; 58import { BusinessError } from '@ohos.base'; 59 60// Certificate data, which is only an example. The certificate data varies with the service. 61let certData = '-----BEGIN CERTIFICATE-----\n' + 62 'MIIBLzCB1QIUO/QDVJwZLIpeJyPjyTvE43xvE5cwCgYIKoZIzj0EAwIwGjEYMBYG\n' + 63 'A1UEAwwPRXhhbXBsZSBSb290IENBMB4XDTIzMDkwNDExMjAxOVoXDTI2MDUzMDEx\n' + 64 'MjAxOVowGjEYMBYGA1UEAwwPRXhhbXBsZSBSb290IENBMFkwEwYHKoZIzj0CAQYI\n' + 65 'KoZIzj0DAQcDQgAEHjG74yMIueO7z3T+dyuEIrhxTg2fqgeNB3SGfsIXlsiUfLTa\n' + 66 'tUsU0i/sePnrKglj2H8Abbx9PK0tsW/VgqwDIDAKBggqhkjOPQQDAgNJADBGAiEA\n' + 67 '0ce/fvA4tckNZeB865aOApKXKlBjiRlaiuq5mEEqvNACIQDPD9WyC21MXqPBuRUf\n' + 68 'BetUokslUfjT6+s/X4ByaxycAA==\n' + 69 '-----END CERTIFICATE-----\n'; 70 71// Convert the certificate data form a string to a Uint8Array. 72function stringToUint8Array(str: string): Uint8Array { 73 let arr: Array<number> = []; 74 for (let i = 0, j = str.length; i < j; i++) { 75 arr.push(str.charCodeAt(i)); 76 } 77 return new Uint8Array(arr); 78} 79 80// Certificate example 81function certSample(): void { 82 let encodingBlob: certFramework.EncodingBlob = { 83 // Convert the certificate data string to a Uint8Array. 84 data: stringToUint8Array(certData), 85 // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format. 86 encodingFormat: certFramework.EncodingFormat.FORMAT_PEM 87 }; 88 89 // Create an X509Cert instance. 90 certFramework.createX509Cert(encodingBlob, (err, x509Cert) => { 91 if (err != null) { 92 // Failed to create the X509Cert instance. 93 console.error('createX509Cert failed, errCode: ' + err.code + ', errMsg: ' + err.message); 94 return; 95 } 96 // The X509Cert instance is successfully created. 97 console.log('createX509Cert success'); 98 99 // Obtain the certificate version. 100 let version = x509Cert.getVersion(); 101 102 // Obtain the serialized data of the certificate. 103 x509Cert.getEncoded((err, data) => { 104 if (err != null) { 105 // Failed to obtain the serialized data of the certificate. 106 console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message); 107 } else { 108 // The serialized data of the certificate is successfully obtained. 109 console.log('getEncoded success'); 110 } 111 }); 112 113 // Obtain the public key object using the getPublicKey() of the upper-level certificate object or this (self-signed) certificate object. 114 try { 115 let pubKey = x509Cert.getPublicKey(); 116 117 // Verify the certificate signature. 118 x509Cert.verify(pubKey, (err, data) => { 119 if (err == null) { 120 // The signature verification is successful. 121 console.log('verify success'); 122 } else { 123 // The signature verification failed. 124 console.error('verify failed, errCode: ' + err.code + ', errMsg: ' + err.message); 125 } 126 }); 127 } catch (error) { 128 let e: BusinessError = error as BusinessError; 129 console.error('getPublicKey failed, errCode: ' + e.code + ', errMsg: ' + e.message); 130 } 131 132 133 // Time represented in a string. 134 let date = '20230930000001Z'; 135 136 // Verify the certificate validity period. 137 try { 138 x509Cert.checkValidityWithDate(date); 139 } catch (error) { 140 let e: BusinessError = error as BusinessError; 141 console.error('checkValidityWithDate failed, errCode: ' + e.code + ', errMsg: ' + e.message); 142 } 143 }); 144} 145``` 146 147## Operating Certificate Extensions 148 149> **NOTE** 150> 151> API version 10 and SDK version 4.0.9 or later must be used. 152 153**When to Use** 154 155Typical operations involve the following: 156 1571. Parse the certificate extension data to generate a certificate extension object. 1582. Obtain certificate extension information, for example, obtaining the object identifiers (OIDs) of certificate extensions and obtaining specific data based on an OID. 1593. Check whether a certificate is a CA certificate. 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 | createCertExtension(inStream : EncodingBlob, callback : AsyncCallback) : void | Creates a **certExtension** instance. This API uses an asynchronous callback to return the result.| 170| cryptoCert | createCertExtension(inStream : EncodingBlob) : Promise | Creates a **certExtension** instance. This API uses a promise to return the result. | 171| CertExtension | getEncoded() : EncodingBlob | Obtains the serialized data of the certificate extension. | 172| CertExtension | getOidList(valueType : ExtensionOidType) : DataArray | Obtains the OIDs of certificate extensions. | 173| CertExtension | getEntry(valueType: ExtensionEntryType, oid : DataBlob) : DataBlob | Obtains the certificate extension object information. | 174| CertExtension | checkCA() : number | Checks whether the certificate is a CA certificate. | 175 176**How to Develop** 177 178Example: Parse the X.509 certificate extension data to generate a **CerExtension** instance and call the related APIs. 179 180```ts 181import certFramework from '@ohos.security.cert'; 182import { BusinessError } from '@ohos.base'; 183 184// Certificate extension data, which is only an example. Set it based on service requirements. 185let extData = new Uint8Array([ 186 0x30, 0x40, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 187 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 188 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, 189 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 190 0x02, 0x01, 0xC6, 0x30, 0x1D, 0x06, 0x03, 0x55, 191 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xE0, 0x8C, 192 0x9B, 0xDB, 0x25, 0x49, 0xB3, 0xF1, 0x7C, 0x86, 193 0xD6, 0xB2, 0x42, 0x87, 0x0B, 0xD0, 0x6B, 0xA0, 194 0xD9, 0xE4 195]); 196 197// Convert the string into a Uint8Array. 198function stringToUint8Array(str: string): Uint8Array { 199 let arr: Array<number> = []; 200 for (let i = 0, j = str.length; i < j; i++) { 201 arr.push(str.charCodeAt(i)); 202 } 203 return new Uint8Array(arr); 204} 205 206// Certificate extension example. 207function certExtensionSample(): void { 208 let encodingBlob: certFramework.EncodingBlob = { 209 data: extData, 210 // Certificate extension format. Currently, only the DER format is supported. 211 encodingFormat: certFramework.EncodingFormat.FORMAT_DER 212 }; 213 214 // Create a CerExtension instance. 215 certFramework.createCertExtension(encodingBlob, (err, certExtension) => { 216 if (err != null) { 217 // The CerExtension instance fails to be created. 218 console.error('createCertExtension failed, errCode: ' + err.code + ', errMsg: ' + err.message); 219 return; 220 } 221 // A CerExtension instance is created. 222 console.log('createCertExtension success'); 223 224 try { 225 // Obtain the serialized data of the CerExtension instance. 226 let encodedData = certExtension.getEncoded(); 227 228 // Obtain the OIDs of the certificate extensions. 229 let oidList = certExtension.getOidList(certFramework.ExtensionOidType.EXTENSION_OID_TYPE_ALL); 230 231 // Obtain the certificate extension information based on a OID. 232 let oidData = '2.5.29.14'; 233 let oid: certFramework.DataBlob = { 234 data: stringToUint8Array(oidData), 235 } 236 let entry = certExtension.getEntry(certFramework.ExtensionEntryType.EXTENSION_ENTRY_TYPE_ENTRY, oid); 237 238 // Check whether the certificate is a CA certificate. 239 let pathLen = certExtension.checkCA(); 240 console.log('test cert extension success'); 241 } catch (err) { 242 let e: BusinessError = err as BusinessError; 243 console.error('operation failed, message: ' + e.message + ' code: ' + e.code); 244 } 245 }); 246} 247``` 248 249## Using the CRL 250 251**When to Use** 252 253Typical operations involve the following: 254 2551. Parse the X.509 CRL data to create an **X509Crl** instance. 2562. Obtain the CRL information, such as the CRL version and type. 2573. Obtain the serialized data of the CRL. 2584. Check whether the certificate is revoked. 2595. Verify the CRL signature. 2606. Obtain the revoked certificates. 261 262**Available APIs** 263 264For details about the APIs, see [Certificate](../reference/apis/js-apis-cert.md). 265 266The table below describes the APIs used in this guide. 267 268| Instance | API | Description | 269| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | 270| 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.| 271| 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. | 272| X509Crl | isRevoked(cert : X509Cert) : boolean | Checks whether the certificate is revoked. | 273| X509Crl | getType() : string | Obtains the CRL type. | 274| X509Crl | getEncoded(callback : AsyncCallback\<EncodingBlob>) : void | Obtains the serialized CRL data. This API uses an asynchronous callback to return the result. | 275| X509Crl | getEncoded() : Promise\<EncodingBlob> | Obtains the serialized CRL data. This API uses a promise to return the result. | 276| X509Crl | verify(key : cryptoFramework.PubKey, callback : AsyncCallback\<void>) : void | Verifies the CRL signature. This API uses an asynchronous callback to return the result. | 277| X509Crl | verify(key : cryptoFramework.PubKey) : Promise\<void> | Verifies the CRL signature. This API uses a promise to return the result. | 278| X509Crl | getVersion() : number | Obtains the CRL version. | 279| X509Crl | getIssuerName() : DataBlob | Obtains the CRL issuer. | 280| X509Crl | getLastUpdate() : string | Obtains the date when the CRL was last updated. | 281| X509Crl | getNextUpdate() : string | Obtains the next update date of the CRL. | 282| X509Crl | getRevokedCert(serialNumber : number) : X509CrlEntry | Obtains the revoked certificate in the CRL based on the serial number. | 283| X509Crl | getRevokedCertWithCert(cert : X509Cert) : X509CrlEntry | Obtains the revoked certificate in the CRL based on the X.509 certificate. | 284| X509Crl | getRevokedCerts(callback : AsyncCallback\<Array\<X509CrlEntry>>) : void | Obtains all revoked certificates in the CRL. This API uses an asynchronous callback to return the result. | 285| X509Crl | getRevokedCerts() : Promise\<Array\<X509CrlEntry>> | Obtains all revoked certificates in the CRL. This API uses a promise to return the result. | 286| X509Crl | getTbsInfo() : DataBlob | Obtains **tbsCertList** of the CRL. | 287| X509Crl | getSignature() : DataBlob | Obtains the CRL signature. | 288| X509Crl | getSignatureAlgName() : string | Obtains the CRL signing algorithm. | 289| X509Crl | getSignatureAlgOid() : string | Obtains the signing algorithm OID of the CRL. | 290| X509Crl | getSignatureAlgParams() : DataBlob | Obtains the signing algorithm parameters of the CRL. | 291 292**How to Develop** 293 294Example: Parse the X.509 CRL data to create an **X509Crl** instance and call APIs to perform CRL operations. 295 296```ts 297import certFramework from '@ohos.security.cert'; 298import cryptoFramework from '@ohos.security.cryptoFramework'; 299import { BusinessError } from '@ohos.base'; 300 301// CRL data, which is only an example. The CRL data varies with the service. 302let crlData = '-----BEGIN X509 CRL-----\n' + 303 'MIHzMF4CAQMwDQYJKoZIhvcNAQEEBQAwFTETMBEGA1UEAxMKQ1JMIGlzc3VlchcN\n' + 304 'MTcwODA3MTExOTU1WhcNMzIxMjE0MDA1MzIwWjAVMBMCAgPoFw0zMjEyMTQwMDUz\n' + 305 'MjBaMA0GCSqGSIb3DQEBBAUAA4GBACEPHhlaCTWA42ykeaOyR0SGQIHIOUR3gcDH\n' + 306 'J1LaNwiL+gDxI9rMQmlhsUGJmPIPdRs9uYyI+f854lsWYisD2PUEpn3DbEvzwYeQ\n' + 307 '5SqQoPDoM+YfZZa23hoTLsu52toXobP74sf/9K501p/+8hm4ROMLBoRT86GQKY6g\n' + 308 'eavsH0Q3\n' + 309 '-----END X509 CRL-----\n' 310 311 312let certData = '-----BEGIN CERTIFICATE-----\n' + 313 'MIIBLzCB1QIUO/QDVJwZLIpeJyPjyTvE43xvE5cwCgYIKoZIzj0EAwIwGjEYMBYG\n' + 314 'A1UEAwwPRXhhbXBsZSBSb290IENBMB4XDTIzMDkwNDExMjAxOVoXDTI2MDUzMDEx\n' + 315 'MjAxOVowGjEYMBYGA1UEAwwPRXhhbXBsZSBSb290IENBMFkwEwYHKoZIzj0CAQYI\n' + 316 'KoZIzj0DAQcDQgAEHjG74yMIueO7z3T+dyuEIrhxTg2fqgeNB3SGfsIXlsiUfLTa\n' + 317 'tUsU0i/sePnrKglj2H8Abbx9PK0tsW/VgqwDIDAKBggqhkjOPQQDAgNJADBGAiEA\n' + 318 '0ce/fvA4tckNZeB865aOApKXKlBjiRlaiuq5mEEqvNACIQDPD9WyC21MXqPBuRUf\n' + 319 'BetUokslUfjT6+s/X4ByaxycAA==\n' + 320 '-----END CERTIFICATE-----\n'; 321 322let pubKeyData = new Uint8Array([ 323 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 324 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xDC, 0x4C, 0x2D, 325 0x57, 0x49, 0x3D, 0x42, 0x52, 0x1A, 0x09, 0xED, 0x3E, 0x90, 0x29, 0x51, 0xF7, 0x70, 0x15, 0xFE, 326 0x76, 0xB0, 0xDB, 0xDF, 0xA1, 0x2C, 0x6C, 0x67, 0x95, 0xDA, 0x63, 0x3D, 0x4F, 0x71, 0x48, 0x8C, 327 0x3E, 0xFA, 0x24, 0x79, 0xE9, 0xF2, 0xF2, 0x20, 0xCB, 0xF1, 0x59, 0x6B, 0xED, 0xC8, 0x72, 0x66, 328 0x6E, 0x31, 0xD4, 0xF3, 0xCE, 0x0B, 0x12, 0xC4, 0x17, 0x39, 0xB4, 0x52, 0x16, 0xD3, 0xE3, 0xC0, 329 0xF8, 0x48, 0xB3, 0xF6, 0x40, 0xD5, 0x47, 0x23, 0x30, 0x7F, 0xA7, 0xC5, 0x5A, 0x5A, 0xBB, 0x5C, 330 0x7B, 0xEF, 0x69, 0xE2, 0x74, 0x35, 0x24, 0x22, 0x25, 0x45, 0x7E, 0xFC, 0xE8, 0xC4, 0x52, 0x65, 331 0xA0, 0x4E, 0xBC, 0xFD, 0x3F, 0xD9, 0x85, 0x14, 0x8A, 0x5A, 0x93, 0x02, 0x24, 0x6C, 0x19, 0xBA, 332 0x81, 0xBE, 0x65, 0x2E, 0xCB, 0xBB, 0xE9, 0x91, 0x7B, 0x7C, 0x47, 0xC2, 0x61, 0x02, 0x03, 0x01, 333 0x00, 0x01 334]); 335 336let priKeyData = new Uint8Array([ 337 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 338 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x61, 0x30, 0x82, 0x02, 0x5D, 0x02, 0x01, 339 0x00, 0x02, 0x81, 0x81, 0x00, 0xDC, 0x4C, 0x2D, 0x57, 0x49, 0x3D, 0x42, 0x52, 0x1A, 0x09, 0xED, 340 0x3E, 0x90, 0x29, 0x51, 0xF7, 0x70, 0x15, 0xFE, 0x76, 0xB0, 0xDB, 0xDF, 0xA1, 0x2C, 0x6C, 0x67, 341 0x95, 0xDA, 0x63, 0x3D, 0x4F, 0x71, 0x48, 0x8C, 0x3E, 0xFA, 0x24, 0x79, 0xE9, 0xF2, 0xF2, 0x20, 342 0xCB, 0xF1, 0x59, 0x6B, 0xED, 0xC8, 0x72, 0x66, 0x6E, 0x31, 0xD4, 0xF3, 0xCE, 0x0B, 0x12, 0xC4, 343 0x17, 0x39, 0xB4, 0x52, 0x16, 0xD3, 0xE3, 0xC0, 0xF8, 0x48, 0xB3, 0xF6, 0x40, 0xD5, 0x47, 0x23, 344 0x30, 0x7F, 0xA7, 0xC5, 0x5A, 0x5A, 0xBB, 0x5C, 0x7B, 0xEF, 0x69, 0xE2, 0x74, 0x35, 0x24, 0x22, 345 0x25, 0x45, 0x7E, 0xFC, 0xE8, 0xC4, 0x52, 0x65, 0xA0, 0x4E, 0xBC, 0xFD, 0x3F, 0xD9, 0x85, 0x14, 346 0x8A, 0x5A, 0x93, 0x02, 0x24, 0x6C, 0x19, 0xBA, 0x81, 0xBE, 0x65, 0x2E, 0xCB, 0xBB, 0xE9, 0x91, 347 0x7B, 0x7C, 0x47, 0xC2, 0x61, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x5A, 0xCF, 0x0F, 348 0xF5, 0xA6, 0x1C, 0x19, 0x65, 0x8C, 0x94, 0x40, 0xF6, 0x84, 0x28, 0x74, 0x40, 0x42, 0x34, 0xDE, 349 0xC3, 0x00, 0x5E, 0x72, 0x4D, 0x96, 0xE9, 0x4C, 0xBD, 0xC9, 0xDB, 0x14, 0x9F, 0xD5, 0xBB, 0xA9, 350 0x0C, 0x20, 0xC2, 0xBE, 0x7A, 0x80, 0x89, 0xEC, 0x99, 0x04, 0xF0, 0xEE, 0x7B, 0x83, 0x20, 0x1D, 351 0x37, 0x19, 0x55, 0x85, 0xF6, 0x8E, 0x3B, 0xFB, 0x16, 0xF3, 0xD3, 0x6F, 0xEE, 0x73, 0x12, 0x53, 352 0xCA, 0x77, 0xD7, 0x6C, 0x29, 0xF5, 0x08, 0xA3, 0x09, 0x01, 0x0B, 0x00, 0x05, 0x57, 0xAD, 0x4D, 353 0xF0, 0x92, 0xB2, 0x5A, 0x8B, 0x19, 0x09, 0x81, 0x86, 0xFE, 0x66, 0xB9, 0x33, 0x88, 0x28, 0xF3, 354 0x37, 0x73, 0x09, 0x5F, 0xD7, 0xC9, 0xC6, 0xFA, 0x13, 0x74, 0xFE, 0xAE, 0x53, 0xA9, 0x71, 0x67, 355 0xCE, 0x3A, 0xE6, 0x8D, 0x35, 0xD1, 0xB8, 0xFD, 0x6F, 0x0D, 0x43, 0xC2, 0xD1, 0x02, 0x41, 0x00, 356 0xF7, 0x33, 0xE5, 0x6C, 0x29, 0x5A, 0x30, 0x58, 0xA4, 0x52, 0x65, 0xA0, 0x39, 0xC2, 0xE8, 0xAE, 357 0x5F, 0xA3, 0x2D, 0x0C, 0x65, 0xB1, 0x7B, 0xFD, 0x92, 0xBF, 0x47, 0x87, 0x97, 0x40, 0xCB, 0x54, 358 0xF9, 0xBB, 0x50, 0x27, 0x70, 0x51, 0xD0, 0xD8, 0x48, 0x0D, 0xC6, 0x47, 0x60, 0xF8, 0x4E, 0x0A, 359 0x32, 0x76, 0x6D, 0xA4, 0xBA, 0x40, 0xE5, 0x58, 0xF8, 0x4A, 0x39, 0x4E, 0xF8, 0x3F, 0x4E, 0x2D, 360 0x02, 0x41, 0x00, 0xE4, 0x23, 0x2A, 0x5F, 0x59, 0xCF, 0x7C, 0x91, 0x24, 0x0D, 0xA2, 0x44, 0x17, 361 0xCD, 0x37, 0xDE, 0x1F, 0x53, 0x4D, 0x33, 0x9F, 0x90, 0x4D, 0xD9, 0x72, 0x64, 0x25, 0xBA, 0xAB, 362 0x47, 0x91, 0xC4, 0x99, 0x95, 0x86, 0xB5, 0x8A, 0xEA, 0x77, 0xF7, 0x64, 0x72, 0x5E, 0xB7, 0xBB, 363 0x16, 0xA1, 0x64, 0xA4, 0xE1, 0x2D, 0x76, 0x6D, 0xEF, 0xB1, 0x5E, 0xD6, 0x17, 0xE8, 0xAA, 0xB6, 364 0xA0, 0xD9, 0x85, 0x02, 0x41, 0x00, 0xDF, 0xC8, 0x5B, 0x28, 0x4F, 0x47, 0x15, 0xFD, 0x28, 0xC4, 365 0x6E, 0xBB, 0x5D, 0x8E, 0xD4, 0x95, 0x06, 0x7E, 0xF1, 0x89, 0x07, 0x86, 0x64, 0x78, 0x69, 0x20, 366 0x3F, 0xE0, 0xBF, 0x4C, 0x28, 0xC6, 0x04, 0x4D, 0x4D, 0x82, 0x66, 0x6B, 0xAA, 0x64, 0x20, 0xD6, 367 0x57, 0x68, 0xC6, 0xA0, 0x02, 0x05, 0xB9, 0x28, 0xFC, 0x98, 0xE3, 0x03, 0x5C, 0x9B, 0xEE, 0x29, 368 0x43, 0x37, 0xFA, 0x03, 0x55, 0x01, 0x02, 0x40, 0x69, 0x5B, 0x7C, 0x24, 0x10, 0xDB, 0xEB, 0x91, 369 0x33, 0xEF, 0x3F, 0xF2, 0xE6, 0x73, 0x15, 0xCB, 0xF4, 0xF7, 0x89, 0x7D, 0xBF, 0xC0, 0xEA, 0xD2, 370 0xF3, 0x2B, 0x20, 0xE9, 0x76, 0x54, 0x55, 0x13, 0x50, 0x42, 0x67, 0xB5, 0xCB, 0x73, 0xC0, 0xF7, 371 0x75, 0x62, 0x04, 0x30, 0x21, 0xAC, 0xAF, 0xD8, 0x44, 0xF4, 0xE1, 0x04, 0x02, 0x7D, 0x61, 0x92, 372 0x84, 0x99, 0x02, 0x10, 0x64, 0xCB, 0x1F, 0xE9, 0x02, 0x41, 0x00, 0xAB, 0x4B, 0x7D, 0x90, 0x7C, 373 0x57, 0x08, 0x6B, 0xC0, 0x43, 0x72, 0x09, 0x8A, 0x18, 0x35, 0x36, 0x64, 0x9D, 0x84, 0x8D, 0xF1, 374 0x84, 0x94, 0x48, 0xC6, 0x80, 0x9D, 0xB9, 0xA2, 0x58, 0x0A, 0x4D, 0x0A, 0xCA, 0x1E, 0xD6, 0x05, 375 0x55, 0x5B, 0xFE, 0xD7, 0xAA, 0x70, 0xED, 0x76, 0xB3, 0x40, 0x2E, 0xA0, 0xB3, 0x32, 0x37, 0xB0, 376 0xA0, 0xB9, 0x96, 0x2D, 0xC4, 0x70, 0xE9, 0x99, 0x10, 0x67, 0x8D 377]); 378 379// Convert the certificate data form a string to a Uint8Array. 380function stringToUint8Array(str: string): Uint8Array { 381 let arr: Array<number> = []; 382 for (let i = 0, j = str.length; i < j; i++) { 383 arr.push(str.charCodeAt(i)); 384 } 385 return new Uint8Array(arr); 386} 387 388// Example of a CRL. 389function crlSample(): void { 390 let encodingBlob: certFramework.EncodingBlob = { 391 // Convert the CRL data from a string to a Uint8Array. 392 data: stringToUint8Array(crlData), 393 // CRL format. Only PEM and DER are supported. In this example, the CRL is in PEM format. 394 encodingFormat: certFramework.EncodingFormat.FORMAT_PEM 395 }; 396 397 // Create an X509Crl instance. 398 certFramework.createX509Crl(encodingBlob, (err, x509Crl) => { 399 if (err != null) { 400 // Failed to create the X509Crl instance. 401 console.error('createX509Crl failed, errCode: ' + err.code + ', errMsg: ' + err.message); 402 return; 403 } 404 // The X509Crl instance is successfully created. 405 console.log('createX509Crl success'); 406 407 // Obtain the CRL version. 408 let version = x509Crl.getVersion(); 409 410 // Obtain the serialized data of the CRL. 411 x509Crl.getEncoded((err, data) => { 412 if (err != null) { 413 // Failed to obtain the serialized data of the certificate. 414 console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message); 415 } else { 416 // The serialized data of the certificate is successfully obtained. 417 console.log('getEncoded success'); 418 } 419 }); 420 421 // Create an X509Cert instance by using createX509Cert() of certFramework. 422 let certBlob: certFramework.EncodingBlob = { 423 data: stringToUint8Array(certData), 424 encodingFormat: certFramework.EncodingFormat.FORMAT_PEM 425 }; 426 certFramework.createX509Cert(certBlob, (err, cert) => { 427 if (err == null) { 428 try { 429 // Check whether the certificate is revoked. 430 let revokedFlag = x509Crl.isRevoked(cert); 431 console.log('revokedFlag is: ' + revokedFlag); 432 } catch (error) { 433 let e: BusinessError = error as BusinessError; 434 console.error('isRevoked failed, errCode: ' + e.code + ', errMsg: ' + e.message); 435 } 436 } else { 437 console.error('create x509 cert failed errCode: ' + err.code + ', errMsg: ' + err.message); 438 } 439 }) 440 441 // 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. 442 try { 443 let keyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_3'); 444 console.log('createAsyKeyGenerator success'); 445 let priEncodingBlob: cryptoFramework.DataBlob = { 446 data: priKeyData, 447 }; 448 let pubEncodingBlob: cryptoFramework.DataBlob = { 449 data: pubKeyData, 450 }; 451 keyGenerator.convertKey(pubEncodingBlob, priEncodingBlob, (e, keyPair) => { 452 if (e == null) { 453 console.log('convert key success'); 454 x509Crl.verify(keyPair.pubKey, (err, data) => { 455 if (err == null) { 456 // The signature verification is successful. 457 console.log('verify success'); 458 } else { 459 // The signature verification failed. 460 console.error('verify failed, errCode: ' + err.code + ', errMsg: ' + err.message); 461 } 462 }); 463 } else { 464 console.error('convert key failed, message: ' + e.message + 'code: ' + e.code); 465 } 466 }) 467 } catch (error) { 468 let e: BusinessError = error as BusinessError; 469 console.error('get pubKey failed, errCode: ' + e.code + ', errMsg: ' + e.message); 470 } 471 472 // Certificate serial number, which must be set based on the service. 473 let serialNumber = 1000; 474 475 // Obtain the revoked certificate based on the serial number. 476 try { 477 let entry = x509Crl.getRevokedCert(serialNumber); 478 console.log('get getRevokedCert success'); 479 } catch (error) { 480 let e: BusinessError = error as BusinessError; 481 console.error('getRevokedCert failed, errCode: ' + e.code + ', errMsg: ' + e.message); 482 } 483 }); 484} 485``` 486 487## Verifying Certificate Chains 488 489**When to Use** 490 491You need to use the certificate chain validator in certificate chain verification. 492 493**Available APIs** 494 495For details about the APIs, see [Certificate](../reference/apis/js-apis-cert.md). 496 497The table below describes the APIs used in this guide. 498 499| Instance | API | Description | 500| ------------------ | ------------------------------------------------------------ | -------------------------------- | 501| cryptoCert | createCertChainValidator(algorithm :string) : CertChainValidator | Creates a **CertChainValidator** instance.| 502| CertChainValidator | validate(certChain : CertChainData, callback : AsyncCallback\<void>) : void | Verifies the certificate chain. This API uses an asynchronous callback to return the result. | 503| CertChainValidator | validate(certChain : CertChainData) : Promise\<void> | Verifies the certificate chain. This API uses a promise to return the result. | 504| CertChainValidator | algorithm : string | Obtains the certificate chain validator algorithm. | 505 506**How to Develop** 507 508Example: Create a **CertChainValidator** instance and verify the certificate chain. 509 510```ts 511import certFramework from '@ohos.security.cert'; 512 513// CA certificate data, which is only an example. The CA certificate data varies with the service. 514let caCertData = '-----BEGIN CERTIFICATE-----\n' + 515 '...\n' + 516 '...\n' + 517 '...\n' + 518 '-----END CERTIFICATE-----\n'; 519 520// End-entity certificate data, which is only an example. The certificate data varies with the service. 521let secondCaCertData = '-----BEGIN CERTIFICATE-----\n' + 522 '...\n' + 523 '...\n' + 524 '...\n' + 525 '-----END CERTIFICATE-----\n'; 526 527// Convert the certificate data form a string to a Uint8Array.. 528function stringToUint8Array(str: string): Uint8Array { 529 let arr: Array<number> = []; 530 for (let i = 0, j = str.length; i < j; i++) { 531 arr.push(str.charCodeAt(i)); 532 } 533 return new Uint8Array(arr); 534} 535 536// Certificate chain validator example. In this example, a two-level certificate chain is verified. 537function certChainValidatorSample(): void { 538 // Certificate chain validator algorithm. Currently, only PKIX is supported. 539 let algorithm = 'PKIX'; 540 541 // Create a CertChainValidator instance. 542 let validator = certFramework.createCertChainValidator(algorithm); 543 544 // CA certificate data. 545 let uint8ArrayOfCaCertData = stringToUint8Array(caCertData); 546 547 // Length of the CA certificate data. 548 let uint8ArrayOfCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOfCaCertData.byteLength]).buffer); 549 550 // End-entity certificate data. 551 let uint8ArrayOf2ndCaCertData = stringToUint8Array(secondCaCertData); 552 553 // Length of the end-entity certificate data. 554 let uint8ArrayOf2ndCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOf2ndCaCertData.byteLength]).buffer); 555 556 // Certificate chain binary data: end-entity certificate data length + end-entity certificate data + CA certificate data length + CA certificate data (in L-V format). 557 let encodingData = new Uint8Array(uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + 558 uint8ArrayOfCaCertDataLen.length + uint8ArrayOfCaCertData.length); 559 for (let i = 0; i < uint8ArrayOf2ndCaCertDataLen.length; i++) { 560 encodingData[i] = uint8ArrayOf2ndCaCertDataLen[i]; 561 } 562 for (let i = 0; i < uint8ArrayOf2ndCaCertData.length; i++) { 563 encodingData[uint8ArrayOf2ndCaCertDataLen.length + i] = uint8ArrayOf2ndCaCertData[i]; 564 } 565 for (let i = 0; i < uint8ArrayOfCaCertDataLen.length; i++) { 566 encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + i] = uint8ArrayOfCaCertDataLen[i]; 567 } 568 for (let i = 0; i < uint8ArrayOfCaCertData.length; i++) { 569 encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + 570 uint8ArrayOfCaCertDataLen.length + i] = uint8ArrayOfCaCertData[i]; 571 } 572 573 let certChainData: certFramework.CertChainData = { 574 // Uint8Array type: L-V format (certificate data length-certificate data) 575 data: encodingData, 576 // Number of certificates. It is 2 in this example. 577 count: 2, 578 // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format. 579 encodingFormat: certFramework.EncodingFormat.FORMAT_PEM 580 }; 581 582 // Verify the certificate chain. 583 validator.validate(certChainData, (err, data) => { 584 if (err != null) { 585 // The operation fails. 586 console.error('validate failed, errCode: ' + err.code + ', errMsg: ' + err.message); 587 } else { 588 // The operation is successful. 589 console.log('validate success'); 590 } 591 }); 592} 593``` 594 595## Managing Revoked Certificates 596 597**When to Use** 598 599Typical operations involve the following: 600 6011. Obtain a revoked certificate instance. 6022. Obtain information, such as the serial number, issuer, and certificate revocation date, of the revoked certificate. 6033. Obtain the serialized data of the revoked certificate. 604 605**Available APIs** 606 607For details about the APIs, see [Certificate](../reference/apis/js-apis-cert.md). 608 609The table below describes the APIs used in this guide. 610 611| Instance | API | Description | 612| ------------ | ----------------------------------------------------------- | ---------------------------------------- | 613| X509CrlEntry | getEncoded(callback : AsyncCallback\<EncodingBlob>) : void; | Obtains the serialized data of the revoked certificate. This API uses an asynchronous callback to return the result.| 614| X509CrlEntry | getEncoded() : Promise\<EncodingBlob>; | Obtains the serialized data of the revoked certificate. This API uses a promise to return the result. | 615| X509CrlEntry | getSerialNumber() : number; | Obtains the serial number of the revoked certificate. | 616| X509CrlEntry | getCertIssuer() : DataBlob; | Obtains the issuer of the revoked certificate. | 617| X509CrlEntry | getRevocationDate() : string; | Obtains the revocation date of the revoked certificate. | 618 619**How to Develop** 620 621Example: Obtain a revoked certificate instance and call the APIs. 622 623```ts 624import certFramework from '@ohos.security.cert'; 625import { BusinessError } from '@ohos.base'; 626 627let crlData = '-----BEGIN X509 CRL-----\n' + 628 'MIHzMF4CAQMwDQYJKoZIhvcNAQEEBQAwFTETMBEGA1UEAxMKQ1JMIGlzc3VlchcN\n' + 629 'MTcwODA3MTExOTU1WhcNMzIxMjE0MDA1MzIwWjAVMBMCAgPoFw0zMjEyMTQwMDUz\n' + 630 'MjBaMA0GCSqGSIb3DQEBBAUAA4GBACEPHhlaCTWA42ykeaOyR0SGQIHIOUR3gcDH\n' + 631 'J1LaNwiL+gDxI9rMQmlhsUGJmPIPdRs9uYyI+f854lsWYisD2PUEpn3DbEvzwYeQ\n' + 632 '5SqQoPDoM+YfZZa23hoTLsu52toXobP74sf/9K501p/+8hm4ROMLBoRT86GQKY6g\n' + 633 'eavsH0Q3\n' + 634 '-----END X509 CRL-----\n' 635 636// Convert the certificate data form a string to a Uint8Array. 637function stringToUint8Array(str: string): Uint8Array { 638 let arr: Array<number> = []; 639 for (let i = 0, j = str.length; i < j; i++) { 640 arr.push(str.charCodeAt(i)); 641 } 642 return new Uint8Array(arr); 643} 644 645// Example of a revoked certificate. 646function crlEntrySample(): void { 647 // Create an **X509Crl** instance by using createX509Crl() of certFramework. 648 let encodingBlob: certFramework.EncodingBlob = { 649 // Convert the CRL data from a string to a Uint8Array. 650 data: stringToUint8Array(crlData), 651 // CRL format. Only PEM and DER are supported. In this example, the CRL is in PEM format. 652 encodingFormat: certFramework.EncodingFormat.FORMAT_PEM 653 }; 654 655 // Create an X509Crl instance. 656 certFramework.createX509Crl(encodingBlob, (err, x509Crl) => { 657 if (err != null) { 658 // Failed to create the X509Crl instance. 659 console.error('createX509Crl failed, errCode: ' + err.code + ', errMsg: ' + err.message); 660 return; 661 } 662 console.log('create x509 crl success'); 663 664 // Obtain a revoked certificate instance. In this example, the instance is obtained by using getRevokedCert(). 665 try { 666 let serialNumber = 1000; 667 let crlEntry = x509Crl.getRevokedCert(serialNumber); 668 669 // Obtain the serial number of the revoked certificate. 670 serialNumber = crlEntry.getSerialNumber(); 671 console.log('serialNumber is: ', serialNumber); 672 673 // Obtain the revocation date of the revoked certificate. 674 let date = crlEntry.getRevocationDate(); 675 console.log('revocation date is: ', date); 676 677 // Obtain the serialized data of the revoked certificate instance. 678 crlEntry.getEncoded((err, data) => { 679 if (err != null) { 680 // Failed to obtain the serialized data of the certificate. 681 console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message); 682 } else { 683 // The serialized data of the certificate is successfully obtained. 684 console.log('getEncoded success'); 685 } 686 }); 687 } catch (error) { 688 let e: BusinessError = error as BusinessError; 689 console.error('getRevokedCert failed, errCode: ' + e.code + ', errMsg: ' + e.message); 690 } 691 }) 692} 693```