1# 证书对象的创建、解析和校验 2 3<!--Kit: Device Certificate Kit--> 4<!--Subsystem: Security--> 5<!--Owner: @zxz--3--> 6<!--Designer: @lanming--> 7<!--Tester: @PAFT--> 8<!--Adviser: @zengyawen--> 9 10以校验证书有效性为例,完成证书对象的创建、解析和校验。 11 12## 开发步骤 13 141. 导入[证书算法库框架模块](../../reference/apis-device-certificate-kit/js-apis-cert.md)。 15 ```ts 16 import { cert } from '@kit.DeviceCertificateKit'; 17 ``` 18 192. 基于已有的X509证书数据,调用[cert.createX509Cert](../../reference/apis-device-certificate-kit/js-apis-cert.md#certcreatex509cert)创建证书对象。 20 213. 解析证书的字段信息。 22 此处以获取证书版本、证书序列号、证书颁发者名称、证书主体名称、证书对象的字符串类型数据为例,更多字段信息获取接口请查看[API参考文档](../../reference/apis-device-certificate-kit/js-apis-cert.md#x509cert)。 23 244. 调用[X509Cert.getPublicKey](../../reference/apis-device-certificate-kit/js-apis-cert.md#getpublickey)获取证书中的公钥,并调用[X509Cert.verify](../../reference/apis-device-certificate-kit/js-apis-cert.md#verify)校验签名。示例为自验签场景,因此获取的是本证书中的公钥。应用须结合自身场景获取用于验签的公钥。 25 265. 调用[X509Cert.checkValidityWithDate](../../reference/apis-device-certificate-kit/js-apis-cert.md#checkvaliditywithdate)校验证书有效期。入参date用于确认此日期是否在X509证书有效期内。 27 28```ts 29import { cert } from '@kit.DeviceCertificateKit'; 30import { BusinessError } from '@kit.BasicServicesKit'; 31import { util } from '@kit.ArkTS'; 32 33// 此处仅为示例的证书二进制数据,需根据业务的不同对证书数据进行赋值。 34let certData = '-----BEGIN CERTIFICATE-----\n' + 35 'MIIBLzCB1QIUO/QDVJwZLIpeJyPjyTvE43xvE5cwCgYIKoZIzj0EAwIwGjEYMBYG\n' + 36 'A1UEAwwPRXhhbXBsZSBSb290IENBMB4XDTIzMDkwNDExMjAxOVoXDTI2MDUzMDEx\n' + 37 'MjAxOVowGjEYMBYGA1UEAwwPRXhhbXBsZSBSb290IENBMFkwEwYHKoZIzj0CAQYI\n' + 38 'KoZIzj0DAQcDQgAEHjG74yMIueO7z3T+dyuEIrhxTg2fqgeNB3SGfsIXlsiUfLTa\n' + 39 'tUsU0i/sePnrKglj2H8Abbx9PK0tsW/VgqwDIDAKBggqhkjOPQQDAgNJADBGAiEA\n' + 40 '0ce/fvA4tckNZeB865aOApKXKlBjiRlaiuq5mEEqvNACIQDPD9WyC21MXqPBuRUf\n' + 41 'BetUokslUfjT6+s/X4ByaxycAA==\n' + 42 '-----END CERTIFICATE-----\n'; 43 44// 证书示例 45function certSample(): void { 46 let textEncoder = new util.TextEncoder(); 47 let encodingBlob: cert.EncodingBlob = { 48 // 将证书数据从string类型转换成Unit8Array。 49 data: textEncoder.encodeInto(certData), 50 // 证书格式,仅支持PEM和DER。在此示例中,证书为PEM格式。 51 encodingFormat: cert.EncodingFormat.FORMAT_PEM 52 }; 53 54 // 创建X509Cert实例。 55 cert.createX509Cert(encodingBlob, (err, x509Cert) => { 56 if (err != null) { 57 // 创建X509Cert实例失败。 58 console.error(`createX509Cert failed, errCode:${err.code}, errMsg:${err.message}`); 59 return; 60 } 61 // X509Cert实例创建成功。 62 console.log('createX509Cert success'); 63 64 // 获取证书版本。 65 let version = x509Cert.getVersion(); 66 // 获取证书序列号。 67 let serial = x509Cert.getCertSerialNumber(); 68 console.log(`X509 version: ${version} , X509 serial:${serial}`); 69 70 // 获取证书颁发者名称。 71 let issuerName = x509Cert.getIssuerName(cert.EncodingType.ENCODING_UTF8); 72 console.log(`X509 issuerName: ${issuerName}`); 73 74 // 获取证书主体名称。 75 let subjectNameBin = x509Cert.getSubjectName(cert.EncodingType.ENCODING_UTF8); 76 let encoder = util.TextDecoder.create(); 77 let subjectName = encoder.decodeToString(subjectNameBin.data); 78 console.log(`X509 subjectName: ${subjectName}`); 79 80 // 获取证书对象的字符串类型数据。 81 let certString = x509Cert.toString(cert.EncodingType.ENCODING_UTF8); 82 console.log(`X509 certString: ${certString}`); 83 84 // 使用上级证书对象的getPublicKey()方法或本(自签名)证书对象获取公钥对象。 85 try { 86 let pubKey = x509Cert.getPublicKey(); 87 // 验证证书签名。 88 x509Cert.verify(pubKey, (err, data) => { 89 if (err == null) { 90 // 签名验证成功。 91 console.log('verify success'); 92 } else { 93 // 签名验证失败。 94 console.error(`verify failed, errCode: ${err.code} , errMsg:${err.message}`); 95 } 96 }); 97 } catch (error) { 98 let e: BusinessError = error as BusinessError; 99 console.error(`getPublicKey failed, errCode: ${e.code} , errMsg:${e.message}`); 100 } 101 102 // 用一个字符串代表时间。 103 let date = '20230930000001Z'; 104 105 // 验证证书的有效期。 106 try { 107 x509Cert.checkValidityWithDate(date); 108 } catch (error) { 109 let e: BusinessError = error as BusinessError; 110 console.error(`checkValidityWithDate failed, errCode: ${e.code}, errMsg:${e.message}`); 111 } 112 }); 113} 114``` 115