harmony 鸿蒙证书开发指导

  • 2022-12-22
  • 浏览 (1262)

证书开发指导

说明

本开发指导需使用API version 9及以上版本SDK。

使用证书操作

场景说明

使用证书操作中,典型的场景有:

  1. 解析X509证书数据生成证书对象。
  2. 获取证书信息,比如:证书版本、证书序列号等。
  3. 获取证书对象的序列化数据。
  4. 获取证书公钥。
  5. 证书验签。
  6. 校验证书有效期。

接口及参数说明

详细接口说明可参考API参考

以上场景涉及的常用接口如下表所示:

实例名 接口名 描述
cryptoCert createX509Cert(inStream : EncodingBlob, callback : AsyncCallback<X509Cert>) : void 使用callback方式解析X509证书数据生成证书对象
cryptoCert createX509Cert(inStream : EncodingBlob) : Promise<X509Cert> 使用promise方式解析X509证书数据生成证书对象
X509Cert verify(key : cryptoFramework.PubKey, callback : AsyncCallback<void>) : void 使用callback方式进行证书验签
X509Cert verify(key : cryptoFramework.PubKey) : Promise<void> 使用promise方式进行证书验签
X509Cert getEncoded(callback : AsyncCallback<EncodingBlob>) : void 使用callback方式获取证书序列化数据
X509Cert getEncoded() : Promise<EncodingBlob> 使用promise方式获取证书序列化数据
X509Cert getPublicKey() : cryptoFramework.PubKey 获取证书公钥
X509Cert checkValidityWithDate(date: string) : void 校验证书有效期
X509Cert getVersion() : number 获取证书版本
X509Cert getCertSerialNumber() : bigint10+ 获取证书序列号
X509Cert getIssuerName() : DataBlob 获取证书颁发者名称
X509Cert getSubjectName() : DataBlob 获取证书主体名称
X509Cert getNotBeforeTime() : string 获取证书有效期起始时间
X509Cert getNotAfterTime() : string 获取证书有效期截至时间
X509Cert getSignature() : DataBlob 获取证书签名
X509Cert getSignatureAlgName() : string 获取证书签名算法名称
X509Cert getSignatureAlgOid() : string 获取证书签名算法OID
X509Cert getSignatureAlgParams() : DataBlob 获取证书签名算法参数
X509Cert getKeyUsage() : DataBlob 获取证书秘钥用途
X509Cert getExtKeyUsage() : DataArray 获取证书扩展秘钥用途
X509Cert getBasicConstraints() : number 获取证书基本约束
X509Cert getSubjectAltNames() : DataArray 获取证书主体可选名称
X509Cert getIssuerAltNames() : DataArray 获取证书颁发者可选名称
X509Cert getItem(itemType: CertItemType) : DataBlob10+ 获取X509证书对应的字段

开发步骤

示例:解析X509证书数据生成证书对象,并调用对象方法(包含场景1-6)

import certFramework from '@ohos.security.cert';
import { BusinessError } from '@ohos.base';

// Certificate data, which is only an example. The certificate data varies with the service.
let certData = '-----BEGIN CERTIFICATE-----\n' +
  'MIIBLzCB1QIUO/QDVJwZLIpeJyPjyTvE43xvE5cwCgYIKoZIzj0EAwIwGjEYMBYG\n' +
  'A1UEAwwPRXhhbXBsZSBSb290IENBMB4XDTIzMDkwNDExMjAxOVoXDTI2MDUzMDEx\n' +
  'MjAxOVowGjEYMBYGA1UEAwwPRXhhbXBsZSBSb290IENBMFkwEwYHKoZIzj0CAQYI\n' +
  'KoZIzj0DAQcDQgAEHjG74yMIueO7z3T+dyuEIrhxTg2fqgeNB3SGfsIXlsiUfLTa\n' +
  'tUsU0i/sePnrKglj2H8Abbx9PK0tsW/VgqwDIDAKBggqhkjOPQQDAgNJADBGAiEA\n' +
  '0ce/fvA4tckNZeB865aOApKXKlBjiRlaiuq5mEEqvNACIQDPD9WyC21MXqPBuRUf\n' +
  'BetUokslUfjT6+s/X4ByaxycAA==\n' +
  '-----END CERTIFICATE-----\n';

// Convert the certificate data form a string to a Uint8Array.
function stringToUint8Array(str: string): Uint8Array {
  let arr: Array<number> = [];
  for (let i = 0, j = str.length; i < j; i++) {
    arr.push(str.charCodeAt(i));
  }
  return new Uint8Array(arr);
}

// Certificate example
function certSample(): void {
  let encodingBlob: certFramework.EncodingBlob = {
    // Convert the certificate data string to a Uint8Array.
    data: stringToUint8Array(certData),
    // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format.
    encodingFormat: certFramework.EncodingFormat.FORMAT_PEM
  };

  // Create an X509Cert instance.
  certFramework.createX509Cert(encodingBlob, (err, x509Cert) => {
    if (err != null) {
      // Failed to create the X509Cert instance.
      console.error('createX509Cert failed, errCode: ' + err.code + ', errMsg: ' + err.message);
      return;
    }
    // The X509Cert instance is successfully created.
    console.log('createX509Cert success');

    // Obtain the certificate version.
    let version = x509Cert.getVersion();

    // Obtain the serialized data of the certificate.
    x509Cert.getEncoded((err, data) => {
      if (err != null) {
        // Failed to obtain the serialized data of the certificate.
        console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message);
      } else {
        // The serialized data of the certificate is successfully obtained.
        console.log('getEncoded success');
      }
    });

    // Obtain the public key object using the getPublicKey() of the upper-level certificate object or this (self-signed) certificate object.
    try {
      let pubKey = x509Cert.getPublicKey();

      // Verify the certificate signature.
      x509Cert.verify(pubKey, (err, data) => {
        if (err == null) {
          // The signature verification is successful.
          console.log('verify success');
        } else {
          // The signature verification failed.
          console.error('verify failed, errCode: ' + err.code + ', errMsg: ' + err.message);
        }
      });
    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error('getPublicKey failed, errCode: ' + e.code + ', errMsg: ' + e.message);
    }


    // Time represented in a string.
    let date = '20230930000001Z';

    // Verify the certificate validity period.
    try {
      x509Cert.checkValidityWithDate(date);
    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error('checkValidityWithDate failed, errCode: ' + e.code + ', errMsg: ' + e.message);
    }
  });
}

使用证书扩展域段操作

说明

本场景基于API version 10,OH SDK版本4.0.9及以上。

场景说明

使用证书扩展域段操作中,典型的场景有:

  1. 解析证书扩展域段数据生成证书扩展域段对象。
  2. 获取证书扩展域段信息,比如:证书扩展域段对象标识符列表,根据对象标识符获取具体数据等。
  3. 校验证书是否为CA证书。

接口及参数说明

详细接口说明可参考API参考

以上场景涉及的常用接口如下表所示:

实例名 接口名 描述
cryptoCert createCertExtension(inStream : EncodingBlob, callback : AsyncCallback) : void 使用callback方式创建证书扩展域段的对象
cryptoCert createCertExtension(inStream : EncodingBlob) : Promise 使用promise方式创建证书扩展域段的对象
CertExtension getEncoded() : EncodingBlob 获取证书扩展域段序列化数据
CertExtension getOidList(valueType : ExtensionOidType) : DataArray 获取证书扩展域段对象标识符列表
CertExtension getEntry(valueType: ExtensionEntryType, oid : DataBlob) : DataBlob 获取证书扩展域段对象信息
CertExtension checkCA() : number 校验证书是否为CA证书

开发步骤

示例:解析X509证书扩展域段数据生成证书扩展域段对象,并调用对象方法(包含场景1-3)

import certFramework from '@ohos.security.cert';
import { BusinessError } from '@ohos.base';

// Certificate extension data, which is only an example. Set it based on service requirements.
let extData = new Uint8Array([
  0x30, 0x40, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D,
  0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03,
  0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55,
  0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03,
  0x02, 0x01, 0xC6, 0x30, 0x1D, 0x06, 0x03, 0x55,
  0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xE0, 0x8C,
  0x9B, 0xDB, 0x25, 0x49, 0xB3, 0xF1, 0x7C, 0x86,
  0xD6, 0xB2, 0x42, 0x87, 0x0B, 0xD0, 0x6B, 0xA0,
  0xD9, 0xE4
]);

// Convert the string into a Uint8Array.
function stringToUint8Array(str: string): Uint8Array {
  let arr: Array<number> = [];
  for (let i = 0, j = str.length; i < j; i++) {
    arr.push(str.charCodeAt(i));
  }
  return new Uint8Array(arr);
}

// Certificate extension example.
function certExtensionSample(): void {
  let encodingBlob: certFramework.EncodingBlob = {
    data: extData,
    // Certificate extension format. Currently, only the DER format is supported.
    encodingFormat: certFramework.EncodingFormat.FORMAT_DER
  };

  // Create a CerExtension instance.
  certFramework.createCertExtension(encodingBlob, (err, certExtension) => {
    if (err != null) {
      // The CerExtension instance fails to be created.
      console.error('createCertExtension failed, errCode: ' + err.code + ', errMsg: ' + err.message);
      return;
    }
    // A CerExtension instance is created.
    console.log('createCertExtension success');

    try {
      // Obtain the serialized data of the CerExtension instance.
      let encodedData = certExtension.getEncoded();

      // Obtain the OIDs of the certificate extensions.
      let oidList = certExtension.getOidList(certFramework.ExtensionOidType.EXTENSION_OID_TYPE_ALL);

      // Obtain the certificate extension information based on a OID.
      let oidData = '2.5.29.14';
      let oid: certFramework.DataBlob = {
        data: stringToUint8Array(oidData),
      }
      let entry = certExtension.getEntry(certFramework.ExtensionEntryType.EXTENSION_ENTRY_TYPE_ENTRY, oid);

      // Check whether the certificate is a CA certificate.
      let pathLen = certExtension.checkCA();
      console.log('test cert extension success');
    } catch (err) {
      let e: BusinessError = err as BusinessError;
      console.error('operation failed, message: ' + e.message + ' code: ' + e.code);
    }
  });
}

使用证书吊销列表操作

场景说明

使用证书吊销列表操作中,典型的场景有:

  1. 解析X509证书吊销列表数据生成吊销列表对象。
  2. 获取证书吊销列表信息,比如:证书吊销列表版本、证书吊销列表类型等。
  3. 获取证书吊销列表对象的序列化数据。
  4. 检查证书是否被吊销。
  5. 证书吊销列表验签。
  6. 获取被吊销证书。

接口及参数说明

详细接口说明可参考API参考

以上场景涉及的常用接口如下表所示:

实例名 接口名 描述
cryptoCert createX509Crl(inStream : EncodingBlob, callback : AsyncCallback<X509Crl>) : void 使用callback方式解析X509证书吊销列表数据生成证书吊销列表对象
cryptoCert createX509Crl(inStream : EncodingBlob) : Promise<X509Crl> 使用promise方式解析X509证书吊销列表数据生成证书吊销列表对象
X509Crl isRevoked(cert : X509Cert) : boolean 检查证书是否被吊销
X509Crl getType() : string 获取证书吊销列表类型
X509Crl getEncoded(callback : AsyncCallback<EncodingBlob>) : void 使用callback方式获取证书吊销列表序列化数据
X509Crl getEncoded() : Promise<EncodingBlob> 使用promise方式获取证书吊销列表序列化数据
X509Crl verify(key : cryptoFramework.PubKey, callback : AsyncCallback<void>) : void 使用callback方式进行证书吊销列表验签
X509Crl verify(key : cryptoFramework.PubKey) : Promise<void> 使用Promise方式进行证书吊销列表验签
X509Crl getVersion() : number 获取证书吊销列表版本
X509Crl getIssuerName() : DataBlob 获取证书吊销列表颁发者名称
X509Crl getLastUpdate() : string 获取证书吊销列表lastUpdate日期
X509Crl getNextUpdate() : string 获取证书吊销列表nextUpdate日期
X509Crl getRevokedCert(serialNumber : number) : X509CrlEntry 通过序列号获取证书吊销列表中的被吊销证书
X509Crl getRevokedCertWithCert(cert : X509Cert) : X509CrlEntry 通过X509证书获取证书吊销列表中的被吊销证书
X509Crl getRevokedCerts(callback : AsyncCallback<Array<X509CrlEntry>>) : void 使用callback方式获取证书吊销列表的所有被吊销证书
X509Crl getRevokedCerts() : Promise<Array<X509CrlEntry>> 使用Promise方式获取证书吊销列表的所有被吊销证书
X509Crl getTbsInfo() : DataBlob 获取证书吊销列表的tbsCertList
X509Crl getSignature() : DataBlob 获取证书吊销列表的签名
X509Crl getSignatureAlgName() : string 获取证书吊销列表的签名算法名称
X509Crl getSignatureAlgOid() : string 获取证书吊销列表的签名算法OID
X509Crl getSignatureAlgParams() : DataBlob 获取证书吊销列表的签名算法参数

开发步骤

示例:解析X509证书吊销列表数据生成证书吊销列表对象,并调用对象方法(包含场景1-6)

import certFramework from '@ohos.security.cert';
import cryptoFramework from '@ohos.security.cryptoFramework';
import { BusinessError } from '@ohos.base';

// CRL data, which is only an example. The CRL data varies with the service.
let crlData = '-----BEGIN X509 CRL-----\n' +
  'MIHzMF4CAQMwDQYJKoZIhvcNAQEEBQAwFTETMBEGA1UEAxMKQ1JMIGlzc3VlchcN\n' +
  'MTcwODA3MTExOTU1WhcNMzIxMjE0MDA1MzIwWjAVMBMCAgPoFw0zMjEyMTQwMDUz\n' +
  'MjBaMA0GCSqGSIb3DQEBBAUAA4GBACEPHhlaCTWA42ykeaOyR0SGQIHIOUR3gcDH\n' +
  'J1LaNwiL+gDxI9rMQmlhsUGJmPIPdRs9uYyI+f854lsWYisD2PUEpn3DbEvzwYeQ\n' +
  '5SqQoPDoM+YfZZa23hoTLsu52toXobP74sf/9K501p/+8hm4ROMLBoRT86GQKY6g\n' +
  'eavsH0Q3\n' +
  '-----END X509 CRL-----\n'


let certData = '-----BEGIN CERTIFICATE-----\n' +
  'MIIBLzCB1QIUO/QDVJwZLIpeJyPjyTvE43xvE5cwCgYIKoZIzj0EAwIwGjEYMBYG\n' +
  'A1UEAwwPRXhhbXBsZSBSb290IENBMB4XDTIzMDkwNDExMjAxOVoXDTI2MDUzMDEx\n' +
  'MjAxOVowGjEYMBYGA1UEAwwPRXhhbXBsZSBSb290IENBMFkwEwYHKoZIzj0CAQYI\n' +
  'KoZIzj0DAQcDQgAEHjG74yMIueO7z3T+dyuEIrhxTg2fqgeNB3SGfsIXlsiUfLTa\n' +
  'tUsU0i/sePnrKglj2H8Abbx9PK0tsW/VgqwDIDAKBggqhkjOPQQDAgNJADBGAiEA\n' +
  '0ce/fvA4tckNZeB865aOApKXKlBjiRlaiuq5mEEqvNACIQDPD9WyC21MXqPBuRUf\n' +
  'BetUokslUfjT6+s/X4ByaxycAA==\n' +
  '-----END CERTIFICATE-----\n';

let pubKeyData = new Uint8Array([
  0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
  0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xDC, 0x4C, 0x2D,
  0x57, 0x49, 0x3D, 0x42, 0x52, 0x1A, 0x09, 0xED, 0x3E, 0x90, 0x29, 0x51, 0xF7, 0x70, 0x15, 0xFE,
  0x76, 0xB0, 0xDB, 0xDF, 0xA1, 0x2C, 0x6C, 0x67, 0x95, 0xDA, 0x63, 0x3D, 0x4F, 0x71, 0x48, 0x8C,
  0x3E, 0xFA, 0x24, 0x79, 0xE9, 0xF2, 0xF2, 0x20, 0xCB, 0xF1, 0x59, 0x6B, 0xED, 0xC8, 0x72, 0x66,
  0x6E, 0x31, 0xD4, 0xF3, 0xCE, 0x0B, 0x12, 0xC4, 0x17, 0x39, 0xB4, 0x52, 0x16, 0xD3, 0xE3, 0xC0,
  0xF8, 0x48, 0xB3, 0xF6, 0x40, 0xD5, 0x47, 0x23, 0x30, 0x7F, 0xA7, 0xC5, 0x5A, 0x5A, 0xBB, 0x5C,
  0x7B, 0xEF, 0x69, 0xE2, 0x74, 0x35, 0x24, 0x22, 0x25, 0x45, 0x7E, 0xFC, 0xE8, 0xC4, 0x52, 0x65,
  0xA0, 0x4E, 0xBC, 0xFD, 0x3F, 0xD9, 0x85, 0x14, 0x8A, 0x5A, 0x93, 0x02, 0x24, 0x6C, 0x19, 0xBA,
  0x81, 0xBE, 0x65, 0x2E, 0xCB, 0xBB, 0xE9, 0x91, 0x7B, 0x7C, 0x47, 0xC2, 0x61, 0x02, 0x03, 0x01,
  0x00, 0x01
]);

let priKeyData = new Uint8Array([
  0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
  0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x61, 0x30, 0x82, 0x02, 0x5D, 0x02, 0x01,
  0x00, 0x02, 0x81, 0x81, 0x00, 0xDC, 0x4C, 0x2D, 0x57, 0x49, 0x3D, 0x42, 0x52, 0x1A, 0x09, 0xED,
  0x3E, 0x90, 0x29, 0x51, 0xF7, 0x70, 0x15, 0xFE, 0x76, 0xB0, 0xDB, 0xDF, 0xA1, 0x2C, 0x6C, 0x67,
  0x95, 0xDA, 0x63, 0x3D, 0x4F, 0x71, 0x48, 0x8C, 0x3E, 0xFA, 0x24, 0x79, 0xE9, 0xF2, 0xF2, 0x20,
  0xCB, 0xF1, 0x59, 0x6B, 0xED, 0xC8, 0x72, 0x66, 0x6E, 0x31, 0xD4, 0xF3, 0xCE, 0x0B, 0x12, 0xC4,
  0x17, 0x39, 0xB4, 0x52, 0x16, 0xD3, 0xE3, 0xC0, 0xF8, 0x48, 0xB3, 0xF6, 0x40, 0xD5, 0x47, 0x23,
  0x30, 0x7F, 0xA7, 0xC5, 0x5A, 0x5A, 0xBB, 0x5C, 0x7B, 0xEF, 0x69, 0xE2, 0x74, 0x35, 0x24, 0x22,
  0x25, 0x45, 0x7E, 0xFC, 0xE8, 0xC4, 0x52, 0x65, 0xA0, 0x4E, 0xBC, 0xFD, 0x3F, 0xD9, 0x85, 0x14,
  0x8A, 0x5A, 0x93, 0x02, 0x24, 0x6C, 0x19, 0xBA, 0x81, 0xBE, 0x65, 0x2E, 0xCB, 0xBB, 0xE9, 0x91,
  0x7B, 0x7C, 0x47, 0xC2, 0x61, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x5A, 0xCF, 0x0F,
  0xF5, 0xA6, 0x1C, 0x19, 0x65, 0x8C, 0x94, 0x40, 0xF6, 0x84, 0x28, 0x74, 0x40, 0x42, 0x34, 0xDE,
  0xC3, 0x00, 0x5E, 0x72, 0x4D, 0x96, 0xE9, 0x4C, 0xBD, 0xC9, 0xDB, 0x14, 0x9F, 0xD5, 0xBB, 0xA9,
  0x0C, 0x20, 0xC2, 0xBE, 0x7A, 0x80, 0x89, 0xEC, 0x99, 0x04, 0xF0, 0xEE, 0x7B, 0x83, 0x20, 0x1D,
  0x37, 0x19, 0x55, 0x85, 0xF6, 0x8E, 0x3B, 0xFB, 0x16, 0xF3, 0xD3, 0x6F, 0xEE, 0x73, 0x12, 0x53,
  0xCA, 0x77, 0xD7, 0x6C, 0x29, 0xF5, 0x08, 0xA3, 0x09, 0x01, 0x0B, 0x00, 0x05, 0x57, 0xAD, 0x4D,
  0xF0, 0x92, 0xB2, 0x5A, 0x8B, 0x19, 0x09, 0x81, 0x86, 0xFE, 0x66, 0xB9, 0x33, 0x88, 0x28, 0xF3,
  0x37, 0x73, 0x09, 0x5F, 0xD7, 0xC9, 0xC6, 0xFA, 0x13, 0x74, 0xFE, 0xAE, 0x53, 0xA9, 0x71, 0x67,
  0xCE, 0x3A, 0xE6, 0x8D, 0x35, 0xD1, 0xB8, 0xFD, 0x6F, 0x0D, 0x43, 0xC2, 0xD1, 0x02, 0x41, 0x00,
  0xF7, 0x33, 0xE5, 0x6C, 0x29, 0x5A, 0x30, 0x58, 0xA4, 0x52, 0x65, 0xA0, 0x39, 0xC2, 0xE8, 0xAE,
  0x5F, 0xA3, 0x2D, 0x0C, 0x65, 0xB1, 0x7B, 0xFD, 0x92, 0xBF, 0x47, 0x87, 0x97, 0x40, 0xCB, 0x54,
  0xF9, 0xBB, 0x50, 0x27, 0x70, 0x51, 0xD0, 0xD8, 0x48, 0x0D, 0xC6, 0x47, 0x60, 0xF8, 0x4E, 0x0A,
  0x32, 0x76, 0x6D, 0xA4, 0xBA, 0x40, 0xE5, 0x58, 0xF8, 0x4A, 0x39, 0x4E, 0xF8, 0x3F, 0x4E, 0x2D,
  0x02, 0x41, 0x00, 0xE4, 0x23, 0x2A, 0x5F, 0x59, 0xCF, 0x7C, 0x91, 0x24, 0x0D, 0xA2, 0x44, 0x17,
  0xCD, 0x37, 0xDE, 0x1F, 0x53, 0x4D, 0x33, 0x9F, 0x90, 0x4D, 0xD9, 0x72, 0x64, 0x25, 0xBA, 0xAB,
  0x47, 0x91, 0xC4, 0x99, 0x95, 0x86, 0xB5, 0x8A, 0xEA, 0x77, 0xF7, 0x64, 0x72, 0x5E, 0xB7, 0xBB,
  0x16, 0xA1, 0x64, 0xA4, 0xE1, 0x2D, 0x76, 0x6D, 0xEF, 0xB1, 0x5E, 0xD6, 0x17, 0xE8, 0xAA, 0xB6,
  0xA0, 0xD9, 0x85, 0x02, 0x41, 0x00, 0xDF, 0xC8, 0x5B, 0x28, 0x4F, 0x47, 0x15, 0xFD, 0x28, 0xC4,
  0x6E, 0xBB, 0x5D, 0x8E, 0xD4, 0x95, 0x06, 0x7E, 0xF1, 0x89, 0x07, 0x86, 0x64, 0x78, 0x69, 0x20,
  0x3F, 0xE0, 0xBF, 0x4C, 0x28, 0xC6, 0x04, 0x4D, 0x4D, 0x82, 0x66, 0x6B, 0xAA, 0x64, 0x20, 0xD6,
  0x57, 0x68, 0xC6, 0xA0, 0x02, 0x05, 0xB9, 0x28, 0xFC, 0x98, 0xE3, 0x03, 0x5C, 0x9B, 0xEE, 0x29,
  0x43, 0x37, 0xFA, 0x03, 0x55, 0x01, 0x02, 0x40, 0x69, 0x5B, 0x7C, 0x24, 0x10, 0xDB, 0xEB, 0x91,
  0x33, 0xEF, 0x3F, 0xF2, 0xE6, 0x73, 0x15, 0xCB, 0xF4, 0xF7, 0x89, 0x7D, 0xBF, 0xC0, 0xEA, 0xD2,
  0xF3, 0x2B, 0x20, 0xE9, 0x76, 0x54, 0x55, 0x13, 0x50, 0x42, 0x67, 0xB5, 0xCB, 0x73, 0xC0, 0xF7,
  0x75, 0x62, 0x04, 0x30, 0x21, 0xAC, 0xAF, 0xD8, 0x44, 0xF4, 0xE1, 0x04, 0x02, 0x7D, 0x61, 0x92,
  0x84, 0x99, 0x02, 0x10, 0x64, 0xCB, 0x1F, 0xE9, 0x02, 0x41, 0x00, 0xAB, 0x4B, 0x7D, 0x90, 0x7C,
  0x57, 0x08, 0x6B, 0xC0, 0x43, 0x72, 0x09, 0x8A, 0x18, 0x35, 0x36, 0x64, 0x9D, 0x84, 0x8D, 0xF1,
  0x84, 0x94, 0x48, 0xC6, 0x80, 0x9D, 0xB9, 0xA2, 0x58, 0x0A, 0x4D, 0x0A, 0xCA, 0x1E, 0xD6, 0x05,
  0x55, 0x5B, 0xFE, 0xD7, 0xAA, 0x70, 0xED, 0x76, 0xB3, 0x40, 0x2E, 0xA0, 0xB3, 0x32, 0x37, 0xB0,
  0xA0, 0xB9, 0x96, 0x2D, 0xC4, 0x70, 0xE9, 0x99, 0x10, 0x67, 0x8D
]);

// Convert the certificate data form a string to a Uint8Array.
function stringToUint8Array(str: string): Uint8Array {
  let arr: Array<number> = [];
  for (let i = 0, j = str.length; i < j; i++) {
    arr.push(str.charCodeAt(i));
  }
  return new Uint8Array(arr);
}

// Example of a CRL.
function crlSample(): void {
  let encodingBlob: certFramework.EncodingBlob = {
    // Convert the CRL data from a string to a Uint8Array.
    data: stringToUint8Array(crlData),
    // CRL format. Only PEM and DER are supported. In this example, the CRL is in PEM format.
    encodingFormat: certFramework.EncodingFormat.FORMAT_PEM
  };

  // Create an X509Crl instance.
  certFramework.createX509Crl(encodingBlob, (err, x509Crl) => {
    if (err != null) {
      // Failed to create the X509Crl instance.
      console.error('createX509Crl failed, errCode: ' + err.code + ', errMsg: ' + err.message);
      return;
    }
    // The X509Crl instance is successfully created.
    console.log('createX509Crl success');

    // Obtain the CRL version.
    let version = x509Crl.getVersion();

    // Obtain the serialized data of the CRL.
    x509Crl.getEncoded((err, data) => {
      if (err != null) {
        // Failed to obtain the serialized data of the certificate.
        console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message);
      } else {
        // The serialized data of the certificate is successfully obtained.
        console.log('getEncoded success');
      }
    });

    // Create an X509Cert instance by using createX509Cert() of certFramework.
    let certBlob: certFramework.EncodingBlob = {
      data: stringToUint8Array(certData),
      encodingFormat: certFramework.EncodingFormat.FORMAT_PEM
    };
    certFramework.createX509Cert(certBlob, (err, cert) => {
      if (err == null) {
        try {
          // Check whether the certificate is revoked.
          let revokedFlag = x509Crl.isRevoked(cert);
          console.log('revokedFlag is: ' + revokedFlag);
        } catch (error) {
          let e: BusinessError = error as BusinessError;
          console.error('isRevoked failed, errCode: ' + e.code + ', errMsg: ' + e.message);
        }
      } else {
        console.error('create x509 cert failed errCode: ' + err.code + ', errMsg: ' + err.message);
      }
    })

    // 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.
    try {
      let keyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_3');
      console.log('createAsyKeyGenerator success');
      let priEncodingBlob: cryptoFramework.DataBlob = {
        data: priKeyData,
      };
      let pubEncodingBlob: cryptoFramework.DataBlob = {
        data: pubKeyData,
      };
      keyGenerator.convertKey(pubEncodingBlob, priEncodingBlob, (e, keyPair) => {
        if (e == null) {
          console.log('convert key success');
          x509Crl.verify(keyPair.pubKey, (err, data) => {
            if (err == null) {
              // The signature verification is successful.
              console.log('verify success');
            } else {
              // The signature verification failed.
              console.error('verify failed, errCode: ' + err.code + ', errMsg: ' + err.message);
            }
          });
        } else {
          console.error('convert key failed, message: ' + e.message + 'code: ' + e.code);
        }
      })
    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error('get pubKey failed, errCode: ' + e.code + ', errMsg: ' + e.message);
    }

    // Certificate serial number, which must be set based on the service.
    let serialNumber = 1000;

    // Obtain the revoked certificate based on the serial number.
    try {
      let entry = x509Crl.getRevokedCert(serialNumber);
      console.log('get getRevokedCert success');
    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error('getRevokedCert failed, errCode: ' + e.code + ', errMsg: ' + e.message);
    }
  });
}

使用证书链校验器操作

场景说明

使用证书链校验器操作中,典型的场景:证书链校验。

接口及参数说明

详细接口说明可参考API参考

以上场景涉及的常用接口如下表所示:

实例名 接口名 描述
cryptoCert createCertChainValidator(algorithm :string) : CertChainValidator 使用指定算法生成证书链校验器对象
CertChainValidator validate(certChain : CertChainData, callback : AsyncCallback<void>) : void 使用callback方式校验证书链
CertChainValidator validate(certChain : CertChainData) : Promise<void> 使用promise方式校验证书链
CertChainValidator algorithm : string 证书链校验器算法名称

开发步骤

示例:创建证书链校验器对象,并对证书链数据进行校验(场景1)

import certFramework from '@ohos.security.cert';

// CA certificate data, which is only an example. The CA certificate data varies with the service.
let caCertData = '-----BEGIN CERTIFICATE-----\n' +
  '...\n' +
  '...\n' +
  '...\n' +
  '-----END CERTIFICATE-----\n';

// End-entity certificate data, which is only an example. The certificate data varies with the service.
let secondCaCertData = '-----BEGIN CERTIFICATE-----\n' +
  '...\n' +
  '...\n' +
  '...\n' +
  '-----END CERTIFICATE-----\n';

// Convert the certificate data form a string to a Uint8Array..
function stringToUint8Array(str: string): Uint8Array {
  let arr: Array<number> = [];
  for (let i = 0, j = str.length; i < j; i++) {
    arr.push(str.charCodeAt(i));
  }
  return new Uint8Array(arr);
}

// Certificate chain validator example. In this example, a two-level certificate chain is verified.
function certChainValidatorSample(): void {
  // Certificate chain validator algorithm. Currently, only PKIX is supported.
  let algorithm = 'PKIX';

  // Create a CertChainValidator instance.
  let validator = certFramework.createCertChainValidator(algorithm);

  // CA certificate data.
  let uint8ArrayOfCaCertData = stringToUint8Array(caCertData);

  // Length of the CA certificate data.
  let uint8ArrayOfCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOfCaCertData.byteLength]).buffer);

  // End-entity certificate data.
  let uint8ArrayOf2ndCaCertData = stringToUint8Array(secondCaCertData);

  // Length of the end-entity certificate data.
  let uint8ArrayOf2ndCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOf2ndCaCertData.byteLength]).buffer);

  // Certificate chain binary data: end-entity certificate data length + end-entity certificate data + CA certificate data length + CA certificate data (in L-V format).
  let encodingData = new Uint8Array(uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length +
  uint8ArrayOfCaCertDataLen.length + uint8ArrayOfCaCertData.length);
  for (let i = 0; i < uint8ArrayOf2ndCaCertDataLen.length; i++) {
    encodingData[i] = uint8ArrayOf2ndCaCertDataLen[i];
  }
  for (let i = 0; i < uint8ArrayOf2ndCaCertData.length; i++) {
    encodingData[uint8ArrayOf2ndCaCertDataLen.length + i] = uint8ArrayOf2ndCaCertData[i];
  }
  for (let i = 0; i < uint8ArrayOfCaCertDataLen.length; i++) {
    encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + i] = uint8ArrayOfCaCertDataLen[i];
  }
  for (let i = 0; i < uint8ArrayOfCaCertData.length; i++) {
    encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length +
    uint8ArrayOfCaCertDataLen.length + i] = uint8ArrayOfCaCertData[i];
  }

  let certChainData: certFramework.CertChainData = {
    // Uint8Array type: L-V format (certificate data length-certificate data)
    data: encodingData,
    // Number of certificates. It is 2 in this example.
    count: 2,
    // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format.
    encodingFormat: certFramework.EncodingFormat.FORMAT_PEM
  };

  // Verify the certificate chain.
  validator.validate(certChainData, (err, data) => {
    if (err != null) {
      // The operation fails.
      console.error('validate failed, errCode: ' + err.code + ', errMsg: ' + err.message);
    } else {
      // The operation is successful.
      console.log('validate success');
    }
  });
}

使用被吊销证书操作

场景说明

使用被吊销证书操作中,典型的场景有:

  1. 获取被吊销证书对象。
  2. 获取被吊销证书信息,比如:序列号、证书颁发者、证书吊销日期。
  3. 获取被吊销证书对象的序列化数据。

接口及参数说明

详细接口说明可参考API参考

以上场景涉及的常用接口如下表所示:

实例名 接口名 描述
X509CrlEntry getEncoded(callback : AsyncCallback<EncodingBlob>) : void; 使用callback方式获取被吊销证书的序列化数据
X509CrlEntry getEncoded() : Promise<EncodingBlob>; 使用promise方式获取被吊销证书的序列化数据
X509CrlEntry getSerialNumber() : number; 获取被吊销证书的序列号
X509CrlEntry getCertIssuer() : DataBlob; 获取被吊销证书颁发者
X509CrlEntry getRevocationDate() : string; 获取被吊销证书的吊销日期

开发步骤

示例:获取被吊销证书对象,并调用对象方法(包含场景1-3)

import certFramework from '@ohos.security.cert';
import { BusinessError } from '@ohos.base';

let crlData = '-----BEGIN X509 CRL-----\n' +
  'MIHzMF4CAQMwDQYJKoZIhvcNAQEEBQAwFTETMBEGA1UEAxMKQ1JMIGlzc3VlchcN\n' +
  'MTcwODA3MTExOTU1WhcNMzIxMjE0MDA1MzIwWjAVMBMCAgPoFw0zMjEyMTQwMDUz\n' +
  'MjBaMA0GCSqGSIb3DQEBBAUAA4GBACEPHhlaCTWA42ykeaOyR0SGQIHIOUR3gcDH\n' +
  'J1LaNwiL+gDxI9rMQmlhsUGJmPIPdRs9uYyI+f854lsWYisD2PUEpn3DbEvzwYeQ\n' +
  '5SqQoPDoM+YfZZa23hoTLsu52toXobP74sf/9K501p/+8hm4ROMLBoRT86GQKY6g\n' +
  'eavsH0Q3\n' +
  '-----END X509 CRL-----\n'

// Convert the certificate data form a string to a Uint8Array.
function stringToUint8Array(str: string): Uint8Array {
  let arr: Array<number> = [];
  for (let i = 0, j = str.length; i < j; i++) {
    arr.push(str.charCodeAt(i));
  }
  return new Uint8Array(arr);
}

// Example of a revoked certificate.
function crlEntrySample(): void {
  // Create an **X509Crl** instance by using createX509Crl() of certFramework.
  let encodingBlob: certFramework.EncodingBlob = {
    // Convert the CRL data from a string to a Uint8Array.
    data: stringToUint8Array(crlData),
    // CRL format. Only PEM and DER are supported. In this example, the CRL is in PEM format.
    encodingFormat: certFramework.EncodingFormat.FORMAT_PEM
  };

  // Create an X509Crl instance.
  certFramework.createX509Crl(encodingBlob, (err, x509Crl) => {
    if (err != null) {
      // Failed to create the X509Crl instance.
      console.error('createX509Crl failed, errCode: ' + err.code + ', errMsg: ' + err.message);
      return;
    }
    console.log('create x509 crl success');

    // Obtain a revoked certificate instance. In this example, the instance is obtained by using getRevokedCert().
    try {
      let serialNumber = 1000;
      let crlEntry = x509Crl.getRevokedCert(serialNumber);

      // Obtain the serial number of the revoked certificate.
      serialNumber = crlEntry.getSerialNumber();
      console.log('serialNumber is: ', serialNumber);

      // Obtain the revocation date of the revoked certificate.
      let date = crlEntry.getRevocationDate();
      console.log('revocation date is: ', date);

      // Obtain the serialized data of the revoked certificate instance.
      crlEntry.getEncoded((err, data) => {
        if (err != null) {
          // Failed to obtain the serialized data of the certificate.
          console.error('getEncoded failed, errCode: ' + err.code + ', errMsg: ' + err.message);
        } else {
          // The serialized data of the certificate is successfully obtained.
          console.log('getEncoded success');
        }
      });
    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error('getRevokedCert failed, errCode: ' + e.code + ', errMsg: ' + e.message);
    }
  })
}

相关实例

针对证书开发,有以下相关实例可供参考:

你可能感兴趣的鸿蒙文章

harmony 鸿蒙安全

harmony 鸿蒙访问控制授权申请指导

harmony 鸿蒙访问控制(权限)开发概述

harmony 鸿蒙HarmonyAppProvision配置文件说明

harmony 鸿蒙证书概述

harmony 鸿蒙加解密算法库框架开发指导

harmony 鸿蒙加解密算法库框架概述

harmony 鸿蒙数据防泄漏(DLP)开发指导

harmony 鸿蒙数据防泄漏(DLP)开发概述

harmony 鸿蒙Hap包签名工具指导

0  赞