往期鸿蒙全套实战文章必看:(附带鸿蒙全栈学习资料)


SecurityConfiguration:定制安全传输行为

场景介绍

在软件开发中,安全性是一个非常重要的方面。 Remote Communication Kit 提供的SecurityConfiguration是一个用于定制安全传输行为的工具,可以帮助开发者更好地保护其开发的应用程序。通过合理的配置和使用,可以大大降低应用程序受到攻击的风险。下面将会通过如何使用自定义证书校验来说明。

使用示例

自定义证书校验

Remote Communication Kit会将服务器证书传递给调用方,调用方可以根据自身业务需要,对证书进行校验。例如:证书过期,但客户端不关注日期,此时可以只校验证书的内容,不校验日期。

  1. 导入需要的模块。
    import { rcp } from '@kit.RemoteCommunicationKit';
    import { BusinessError } from '@kit.BasicServicesKit';
  2. 自定义证书逻辑,模拟校验证书的版本是否符合预期。
    // 自定义证书校验器
    const selfDefinedRemoteValidation = (context: rcp.ValidationContext) => {
      // 判断context是否为空或者undefined
      if (context === null) {
        return false;
      }
      // 循环遍历context中x509证书并最后返回证书版本是否符合预期
      for (let i = 0; i <= context.x509Certs.length; i++) {
        let cert = context.x509Certs[i];
        if (cert === null) {
          console.error(`Cert error: ${cert}`);
          continue;
        }
        console.info(`Cert succeeded: ${cert}`);
        // 注意,此处只是模拟证书版本,实际请根据业务进行判断
        return cert.getVersion() === 0
      }
      return true;
    }
  3. 将定义好的自定义证书校验器配置到configuration中,并利用fetch发起请求。
    const request = new rcp.Request('https://www.example.com');
    // 将证书校验器配置到session中并选择TLS版本
    const session =
      rcp.createSession({
        requestConfiguration: {
          security: { remoteValidation: selfDefinedRemoteValidation, tlsOptions: { tlsVersion: 'TlsV1.3' } }
        }
      });
    session.fetch(request).then((response: rcp.Response) => {
      console.info(`Http response: ${response}`);
    }).catch((err: BusinessError) => {
      console.error(`Response error: ${JSON.stringify(err)}`)
    })

双向证书校验

是一种加密通信机制,用于在客户端和服务器之间建立可信的连接。通过交换证书和公钥来验证双方的身份,并确保数据的完整性和隐私。

  1. 导入需要的模块
    import { rcp } from '@kit.RemoteCommunicationKit'
    import { BusinessError } from '@kit.BasicServicesKit';
    import { fileIo } from '@kit.CoreFileKit';
  2. 定义readFile函数,用于异步读取文件中的证书内容。首先定义文件路径,然后打开文件并读取文件内容。
    let readFile = async () => {
        // 定义文件路径,请根据业务自行定义
        let pathDir = "/path/files/";
        // 定义文件路径,请根据业务自行定义
        let filePath = pathDir + "/client.crt";
        // 使用 fileIo.open 方法打开文件
        fileIo.open(filePath, fileIo.OpenMode.READ_WRITE).then((file: fileIo.File) => {
          // 创建一个 4096 字节的缓冲区用于存储读取的数据
          let buf = new ArrayBuffer(4096);
          // 使用 fileIo.read 方法读取文件内容
          fileIo.read(file.fd, buf, (err: BusinessError, readLen: number) => {
            if (err) {
              console.error(`Failed with error message: code is ${err.code}, message is ${err.message}`);
            } else {
              // 将读取的数据转换为字符串
              let content = String.fromCharCode(...new Uint8Array(buf.slice(0, readLen)));
              console.info(`Cert data: ${content}`);
              fileIo.closeSync(file);
            }
          });
        }).catch((err: BusinessError) => {
          console.error(`Open failed with error message: code is ${err.code}, message is ${err.message}`);
        })
      }
  3. 定义getCert函数,用于异步使用读取到的证书内容进行HTTPS请求的验证。使用 rcp.createSession 创建一个网络请求会话,然后创建一个GET请求,并设置请求的证书配置,包括证书内容、类型、密钥和密钥密码。最后,使用 session.fetch发送请求,并处理响应或错误。
    let getCert = async (content: string) => {
      // 定义服务器地址
      let kHttpServerAddress = "https://www.example.com/fetch";
      // 创建会话并发送请求
      try {
        const session = rcp.createSession();
        const request = new rcp.Request(kHttpServerAddress, "GET");
        request.configuration = {
          security: {
            certificate: {
              content: content,
              type: "PEM",
              key: " ",
              keyPassword: " "
            }
          }
        }
        const response = await session.fetch(request);
        console.info(`${kHttpServerAddress} certificate verification succeeded, message is ${response}`);
      } catch (err) {
        console.error(`${kHttpServerAddress} certificate verification failed: code is ${err.code}, message is ${err.message}`);
      }
    }

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐