HarmonyOS AES128/CBC/NoPadding加密模式报错

AES128/CBC/NoPadding加密模式报错

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/crypto-aes-sym-encrypt-decrypt-cbc-V5

将上面示例中的加密模式AES128|CBC|PKCS7改成AES128/CBC/NoPadding就会报错 AES CBC “Error: create C cipher fail!“, error code: 801

HarmonyOS
2天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
shlp

加解密可以使用三方库crypto-js实现,链接如下:

https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Fcrypto-js

参考示例如下:

pages文件夹下index页面:

import Algorithm from '../viewModel/Algorithm'
import { SelectData } from '../comm/SelectData'
import { TextAndSelect } from '../view/TextAndSelect'
import { TextAndTextInput } from '../view/TextAndTextInput'
import { CompleteTips } from '../view/CompleteTips'

const TAG: string = 'cryptoToolbox'

@Entry
@Component
struct Index {
  @State plaintext: string = '' // 明文 (密码)
  @State ciphertext: string = '' // 密文
  @State secretKey: string = '' // 密钥 (盐值)
  @State algorithmTypeId: number = 0 // 算法类型id
  @State @Watch('algorithmTypeUpdate') algorithmType: string = '消息摘要' // 算法类型
  @State algorithmId: number = 0 // 算法id
  @State algorithm: string = 'MD5' // 算法
  @State modeId: number = 0 // 模式id
  @State mode: string = 'ECB' // 模式
  @State padId: number = 0 // 填充id
  @State pad: string = 'Pkcs7' // 填充
  @State encodingId: number = 0 // 密文编码id
  @State encoding: string = 'Hex' // 密文编码
  @State iv: string = '' // 偏移量
  @State outputLengthId: number = 0 // SHA3输出长度id
  @State outputLength: string = '224' // SHA3输出长度
  @State doType: '加密' | '解密' = '加密' // 算法类别
  @State consumeTime: number = 0 // 算法耗时
  @State keySize: string = '' // 密钥长度
  @State iterations: string = '' // 迭代次数
  // 输入框状态
  @State plaintextIsEditing: boolean = false
  @State ciphertextIsEditing: boolean = false
  // 下拉框数据
  @State algorithmTypeSelectOption: SelectOption[] = []
  @State algorithmSelectOption: SelectOption[] = []
  @State modeSelectOption: SelectOption[] = []
  @State padSelectOption: SelectOption[] = []
  @State encodingSelectOption: SelectOption[] = []
  @State SHAVersionSelectOption: SelectOption[] = []
  // 成功弹框
  private dialogController: CustomDialogController = new CustomDialogController({
    builder: CompleteTips({
      type: this.doType,
      consumeTime: this.consumeTime
    }),
    alignment: DialogAlignment.Top, // 可设置dialog的对齐方式,设定显示在底部或中间等,默认为底部显示
    offset: { dx: 0, dy: 40 },
    customStyle: true,
    isModal: false,
    showInSubWindow: true
  })

  // 算法类型变更
  algorithmTypeUpdate() {
    // 算法类型改变时重新装填算法下拉框数据
    this.algorithmSelectOption = []
    SelectData.algorithmTypeData[this.algorithmTypeId].data.forEach((value: ESObject, key: string) => {
      this.algorithmSelectOption.push({ value: key })
    })
    this.algorithmId = 0
    this.algorithm = Array.from(SelectData.algorithmTypeData[this.algorithmTypeId].data)[this.algorithmId][0]
  }

  // 执行加密与解密
  doCrypt(doType: string) {
    const start: number = new Date().getTime()
    if (doType === '加密') {
      this.ciphertext = Algorithm.encrypt({
        algorithmTypeId: this.algorithmTypeId, // 算法类型Id
        algorithm: this.algorithm, // 算法
        plaintext: this.plaintext, // 明文
        ciphertext: this.ciphertext, // 密文
        secretKey: this.secretKey, // 密钥
        mode: this.mode, // 模式
        pad: this.pad, // 填充
        encoding: this.encoding, // 密文编码
        iv: this.iv, // 偏移量
        outputLength: this.outputLength, // SHA3输出长度
        keySize: this.keySize, // 密钥长度
        iterations: this.iterations // 迭代次数
      })
    } else if (doType === '解密') {
      // 调用解密函数
      this.plaintext = Algorithm.decrypt({
        algorithmTypeId: this.algorithmTypeId, // 算法类型Id
        algorithm: this.algorithm, // 算法
        plaintext: this.plaintext, // 明文
        ciphertext: this.ciphertext, // 密文
        secretKey: this.secretKey, // 密钥
        mode: this.mode, // 模式
        pad: this.pad, // 填充
        encoding: this.encoding, // 密文编码
        iv: this.iv, // 偏移量
        outputLength: this.outputLength, // SHA3输出长度
        keySize: this.keySize, // 密钥长度
        iterations: this.iterations // 迭代次数
      })
    } else {
      throw new Error('算法类别只有加密与解密,没有第三种!')
    }
    const end: number = new Date().getTime()
    console.log(TAG, `${doType}完成,耗时: ${this.consumeTime}ms`)
    console.log(TAG, `${doType}结果: ${doType === '加密' ? this.ciphertext : this.plaintext}`)

    // 拉起提示弹框
    this.consumeTime = end - start
    this.doType = doType
    this.dialogController.close()
    this.dialogController.open()
  }

  // 清空算法参数
  clearOption() {
    this.plaintext = ''
    this.ciphertext = ''
    this.secretKey = ''
    this.iv = ''
    this.keySize = ''
    this.iterations = ''
  }

  // 数据初始化
  aboutToAppear() {
    // 装填算法类型下拉框数据
    SelectData.algorithmTypeData.forEach((value) => {
      this.algorithmTypeSelectOption.push({ value: value.type })
    })
    // 装填算法下拉框数据
    SelectData.algorithmTypeData[this.algorithmTypeId].data.forEach((value: ESObject, key: string) => {
      this.algorithmSelectOption.push({ value: key })
    })
    // 装填模式下拉框数据
    SelectData.modeData.forEach((value, key: string) => {
      this.modeSelectOption.push({ value: key })
    })
    // 装填填充下拉框数据
    SelectData.padData.forEach((value, key: string) => {
      this.padSelectOption.push({ value: key })
    })
    // 装填SHA3输出长度下拉框数据
    SelectData.outputLengthData.forEach((value: string) => {
      this.SHAVersionSelectOption.push({ value: value })
    })
    // 装填密文编码下拉框数据
    SelectData.encodingData.forEach((value, key: string) => {
      this.encodingSelectOption.push({ value: key })
    })
  }

  build() {
    Column() {
      RelativeContainer() {
        // 标题区域
        Row() {
          TextAndSelect({
            textValue: '类型',
            fontSize: 15,
            selectOption: this.algorithmTypeSelectOption,
            selectValue: this.algorithmType,
            selectId: this.algorithmTypeId,
            selectWidth: 130,
            selectHeight: 30
          })
            .margin({ right: 4 })
          TextAndSelect({
            textValue: '算法',
            fontSize: 15,
            selectOption: this.algorithmSelectOption,
            selectValue: this.algorithm,
            selectId: this.algorithmId,
            selectWidth: 130,
            selectHeight: 30
          })
            .margin({ left: 4 })
        }
        .width('100%')
        .height(45)
        .justifyContent(FlexAlign.Center)
        .alignRules({
          top: { anchor: "__container__", align: VerticalAlign.Top },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
        .id("row1")

        // 明文显示区
        Row() {
          TextArea({ text: this.plaintext, placeholder: "明文" })
            .placeholderFont({ size: 20, weight: 400 })
            .fontSize(20)
            .onEditChange(() => {
              this.plaintextIsEditing = !this.plaintextIsEditing
            })
            .borderWidth(this.plaintextIsEditing ? 2 : 1)
            .borderColor(this.plaintextIsEditing ? Color.Blue : Color.Black)
            .padding(this.plaintextIsEditing ? 10 : 11)
            .maxLength(10000)
            .showCounter(true)
            .onChange((value: string) => {
              this.plaintext = value
              console.log(TAG, '明文: ' + this.plaintext)
            })
            .height('100%')
            .width('100%')
        }
        .width('95%')
        .height('30%')
        .justifyContent(FlexAlign.Center)
        .alignRules({
          top: { anchor: "row1", align: VerticalAlign.Bottom },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
        .id("row2")

        // 操作区
        Row() {
          Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Center }) {
            if (this.algorithmTypeId === 0 && this.algorithmId === 6) {
              TextAndSelect({
                textValue: '输出长度',
                selectOption: this.SHAVersionSelectOption,
                selectValue: this.outputLength,
                selectId: this.outputLengthId,
                selectWidth: 100
              })
                .margin({
                  top: 2,
                  bottom: 2,
                  left: 10,
                  right: 10
                })
            }
            if (this.algorithmTypeId === 3) {
              if (this.algorithmId === 0 || this.algorithmId === 1 || this.algorithmId === 2) {
                TextAndSelect({
                  textValue: '模式',
                  selectOption: this.modeSelectOption,
                  selectValue: this.mode,
                  selectId: this.modeId,
                  selectWidth: 90
                })
                  .margin({
                    top: 2,
                    bottom: 2,
                    left: 10,
                    right: 10
                  })
                TextAndSelect({
                  textValue: '填充',
                  selectOption: this.padSelectOption,
                  selectValue: this.pad,
                  selectId: this.padId,
                  selectWidth: 145
                })
                  .margin({
                    top: 2,
                    bottom: 2,
                    left: 10,
                    right: 10
                  })
              }
              if (this.algorithmId !== 3 && this.algorithmId !== 4) {
                if (this.modeId !== 0 || this.algorithmId === 5 || this.algorithmId === 6) {
                  TextAndTextInput({
                    textValue: '偏移量',
                    inputValue: this.iv,
                    inputWidth: 140
                  })
                    .margin({
                      top: 2,
                      bottom: 2,
                      left: 10,
                      right: 10
                    })
                }
              }
            }
            if (this.algorithmTypeId !== 0) {
              TextAndTextInput({
                textValue: this.algorithmTypeId === 2 ? '盐 值' : '密 钥',
                inputValue: this.secretKey,
                inputWidth: 140
              })
                .margin({
                  top: 2,
                  bottom: 2,
                  left: 10,
                  right: 10
                })
            }
            if (this.algorithmTypeId === 2) {
              TextAndTextInput({
                textValue: '密钥长度',
                inputValue: this.keySize,
                inputWidth: 100,
                inputType: InputType.Number
              })
                .margin({
                  top: 2,
                  bottom: 2,
                  left: 10,
                  right: 10
                })
              TextAndTextInput({
                textValue: '迭代次数',
                inputValue: this.iterations,
                inputWidth: 100,
                inputType: InputType.Number
              })
                .margin({
                  top: 2,
                  bottom: 2,
                  left: 10,
                  right: 10
                })
            }

            // 按钮区
            Row() {
              Button('加密', { type: ButtonType.Normal })
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
                .fontColor(Color.Black)
                .backgroundColor('#4497FF')
                .height(30)
                .width(70)
                .margin({
                  top: 2,
                  bottom: 2,
                  left: 10,
                  right: 10
                })
                .onClick(() => {
                  this.doCrypt('加密')
                })
              // 只有加解密算法才能解密
              Button('解密', { type: ButtonType.Normal })
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
                .fontColor(Color.Black)
                .stateEffect(this.algorithmTypeId === 3 ? true : false)
                .backgroundColor(this.algorithmTypeId === 3 ? '#4497FF' : '#c1c1c1')
                .width(70)
                .height(30)
                .margin({
                  top: 2,
                  bottom: 2,
                  left: 10,
                  right: 10
                })
                .onClick(() => {
                  if (this.algorithmTypeId === 3) {
                    this.doCrypt('解密')
                  }
                })
              Button('清空', { type: ButtonType.Normal })
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
                .fontColor(Color.Black)
                .backgroundColor('#4497FF')
                .width(70)
                .height(30)
                .margin({
                  top: 2,
                  bottom: 2,
                  left: 10,
                  right: 10
                })
                .onClick(() => {
                  this.clearOption()
                })
            }

            TextAndSelect({
              textValue: '密文编码',
              selectOption: this.encodingSelectOption,
              selectValue: this.encoding,
              selectId: this.encodingId,
              selectWidth: 120
            })
              .margin({
                top: 2,
                bottom: 2,
                left: 10,
                right: 10
              })
          }
        }
        .width('100%')
        .alignRules({
          top: { anchor: "row2", align: VerticalAlign.Bottom },
          middle: { anchor: "__container__", align: HorizontalAlign.Center },
          bottom: { anchor: "row4", align: VerticalAlign.Top }
        })
        .id("row3")

        // 密文显示区
        Row() {
          TextArea({ text: this.ciphertext, placeholder: "密文" })
            .placeholderFont({ size: 20, weight: 400 })
            .fontSize(20)
            .onEditChange(() => {
              this.ciphertextIsEditing = !this.ciphertextIsEditing
            })
            .borderWidth(this.ciphertextIsEditing ? 2 : 1)
            .borderColor(this.ciphertextIsEditing ? Color.Blue : Color.Black)
            .padding(this.plaintextIsEditing ? 10 : 11)
            .maxLength(10000)
            .showCounter(true)
            .onChange((value: string) => {
              this.ciphertext = value
              console.log(TAG, '密文: ' + this.ciphertext)
            })
            .height('100%')
            .width('100%')
        }
        .width('95%')
        .height('30%')
        .margin({ bottom: 5 })
        .alignRules({
          bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
        .id("row4")
      }
    }
    .height('100%')
  }
}

common文件夹下SelectData页面:

import CryptoJS from '@ohos/crypto-js'

export class SelectData {

  // 消息摘要算法
  static mdData: Map<string, CryptoJS.HasherHelper> = new Map([
    ['MD5', CryptoJS.MD5],
    ['SHA1', CryptoJS.SHA1],
    ['SHA224', CryptoJS.SHA224],
    ['SHA256', CryptoJS.SHA256],
    ['SHA384', CryptoJS.SHA384],
    ['SHA512', CryptoJS.SHA512],
    ['SHA3', CryptoJS.SHA3],
    ['RIPEMD160', CryptoJS.RIPEMD160]
  ])

  // 消息认证码算法
  static hmacData: Map<string, CryptoJS.HmacHasherHelper> = new Map([
    ['Hmac-MD5', CryptoJS.HmacMD5],
    ['Hmac-SHA1', CryptoJS.HmacSHA1],
    ['Hmac-SHA224', CryptoJS.HmacSHA224],
    ['Hmac-SHA256', CryptoJS.HmacSHA256],
    ['Hmac-SHA384', CryptoJS.HmacSHA384],
    ['Hmac-SHA512', CryptoJS.HmacSHA512],
    ['Hmac-SHA3', CryptoJS.HmacSHA3],
    ['Hmac-RIPEMD160', CryptoJS.HmacRIPEMD160]
  ])

  // 密钥派生算法
  static KeyDerivationData: Map<string, CryptoJS.HasherStatic> = new Map([
    ['PBKDF2-MD5', CryptoJS.algo.MD5],
    ['PBKDF2-SHA1', CryptoJS.algo.SHA1],
    ['PBKDF2-SHA224', CryptoJS.algo.SHA224],
    ['PBKDF2-SHA256', CryptoJS.algo.SHA256],
    ['PBKDF2-SHA384', CryptoJS.algo.SHA384],
    ['PBKDF2-SHA512', CryptoJS.algo.SHA512],
    ['PBKDF2-SHA3', CryptoJS.algo.SHA3],
    ['PBKDF2-RIPEMD160', CryptoJS.algo.RIPEMD160]
  ])

  // 加解密算法
  static cipherData: Map<string, CryptoJS.CipherHelper> = new Map([
    ['AES', CryptoJS.AES],
    ['DES', CryptoJS.DES],
    ['TripleDES', CryptoJS.TripleDES],
    ['RC4', CryptoJS.RC4],
    ['RC4Drop', CryptoJS.RC4Drop],
    ['Rabbit', CryptoJS.Rabbit],
    ['RabbitLegacy', CryptoJS.RabbitLegacy]
  ])

  // 算法数据
  static algorithmTypeData: AlgorithmTypeData[] = [
    {
      type: '消息摘要', data: this.mdData
    },
    {
      type: '消息认证码', data: this.hmacData
    },
    {
      type: '密钥派生', data: this.KeyDerivationData
    },
    {
      type: '加解密', data: this.cipherData
    }
  ]

  static algorithmTypeData1: Record<string, ESObject> = {
    '消息摘要': [
      { 'MD5': CryptoJS.MD5 },
      { 'SHA1': CryptoJS.SHA1 },
      { 'SHA256': CryptoJS.SHA256 },
    ]
  }

  // 模式数据
  static modeData: Map<string, CryptoJS.BlockCipherMode> = new Map([
    ['ECB', CryptoJS.mode.ECB],
    ['CBC', CryptoJS.mode.CBC],
    ['CTR', CryptoJS.mode.CTR],
    ['CFB', CryptoJS.mode.CFB],
    ['OFB', CryptoJS.mode.OFB]
  ])

  // 填充数据
  static padData: Map<string, CryptoJS.Padding> = new Map([
    ['Pkcs7', CryptoJS.pad.Pkcs7],
    ['AnsiX923', CryptoJS.pad.AnsiX923],
    ['Iso10126', CryptoJS.pad.Iso10126],
    ['Iso97971', CryptoJS.pad.Iso97971],
    ['ZeroPadding', CryptoJS.pad.ZeroPadding],
    ['NoPadding', CryptoJS.pad.NoPadding]
  ])

  // SHA3输出长度
  static outputLengthData: string[] = ['224', '256', '384', '512']

  // 密文编码数据
  static encodingData: Map<string, CryptoJS.Encoder> = new Map([
    ['Hex', CryptoJS.enc.Hex],
    ['Base64', CryptoJS.enc.Base64]
  ])
}

export interface AlgorithmTypeData {
  type: string
  data: Map<string, ESObject>
}

mode文件夹下AlgorithmOption 页面:

import CryptoJS from '@ohos/crypto-js'

// 算法传入参数
export interface AlgorithmOption {
  algorithmTypeId: number // 算法类型Id
  algorithm: string // 算法
  plaintext: string // 明文
  ciphertext: string // 密文
  secretKey: string // 密钥
  mode: string // 模式
  pad: string // 填充
  encoding: string // 密文编码
  iv: string // 偏移量
  outputLength: string // SHA3输出长度
  keySize: string // 密钥长度
  iterations: string // 迭代次数
}

// 算法转换参数
export interface AssignParamResult {
  algorithmTypeId: number // 算法类型Id
  // algorithm: CryptoJS.HasherHelper | CryptoJS.HmacHasherHelper | CryptoJS.HasherStatic | CryptoJS.CipherHelper // 算法
  algorithm: ESObject // 算法
  plaintext: string // 明文
  ciphertext: string // 密文
  secretKey: string // 密钥
  mode?: CryptoJS.BlockCipherMode // 模式
  pad?: CryptoJS.Padding // 填充
  encoding?: CryptoJS.Encoder // 密文编码
  iv: string // 偏移量
  outputLength: number // SHA3输出长度
  keySize: number // 密钥长度
  iterations: number // 迭代次数
}

// 消息摘要算法参数
export interface MDOption {
  hasherHelper: CryptoJS.HasherHelper // 哈希算法
  plaintext: string // 明文
  encoding?: CryptoJS.Encoder // 密文编码
  outputLength?: number // SHA3输出长度
}

// 消息认证码算法参数
export interface HMACOption {
  hmacHasherHelper: CryptoJS.HmacHasherHelper // HMAC哈希算法
  plaintext: string // 明文
  secretKey: string // 密钥
  encoding?: CryptoJS.Encoder // 密文编码
}

// 密钥派生算法参数
export interface KeyDerivationOption {
  hasherStatic: CryptoJS.HasherStatic // 哈希算法
  password: string // 密码 (plaintext)
  salt: string // 盐值 (secretKey)
  keySize: number // 密钥长度
  iterations: number // 迭代次数
  encoding?: CryptoJS.Encoder // 密文编码
}

// 加解密算法参数
export interface CipherOption {
  CipherHelper: CryptoJS.CipherHelper // 加密算法
  plaintext?: string // 明文
  ciphertext?: string // 密文
  secretKey: string // 密钥
  mode?: CryptoJS.BlockCipherMode // 模式
  pad?: CryptoJS.Padding // 填充
  iv: string // 偏移量
  encoding?: CryptoJS.Encoder // 密文编码
}

view文件夹下CompleteTips页面:

const TAG: string = 'cryptoToolbox== '

// 算法完成提示框组件
@CustomDialog
export struct CompleteTips {
  controller: CustomDialogController
  type: string = ''
  consumeTime: number = 0
  timeId = -1

  aboutToAppear(): void {
    this.timeId = setTimeout(() => {
      this.controller.close()
    }, 1500)
  }

  aboutToDisappear(): void {
    clearTimeout(this.timeId)
  }

  build() {
    Row() {
      Text() {
        Span(this.type)
          .fontColor(Color.Red)
        Span('完成,耗时: ')
        Span(this.consumeTime.toString())
          .fontColor(Color.Red)
        Span(' ms')
      }
      .fontSize(16)
    }
    .height(60)
    .width(200)
    .backgroundColor('#E2F1DC')
    .justifyContent(FlexAlign.Center)
  }
}

view文件夹下TextAndSelect页面:

const TAG: string = 'cryptoToolbox'

// 文本 + 下拉框组件
@Component
export struct TextAndSelect {
  textValue: string = ''
  fontSize?: number = 16
  @Prop selectOption: SelectOption[] = []
  @Link selectValue: string
  @Link selectId: number
  selectWidth: number = 0
  selectHeight?: number = 30

  build() {
    Row() {
      Text(this.textValue + ':')
        .fontSize(this.fontSize)
        .fontWeight(FontWeight.Bold)
        .textAlign(TextAlign.End)
        .margin({ right: 4 })

      Select(this.selectOption)
        .selected(this.selectId)
        .value(this.selectValue)
        .font({ size: this.fontSize, weight: FontWeight.Bold })
        .selectedOptionFont({ size: this.fontSize, weight: 400 })
        .optionFont({ size: this.fontSize, weight: 400 })
        .onSelect((index: number, value: string) => {
          this.selectId = index
          this.selectValue = value
          console.log(TAG, `${this.textValue}: ${this.selectValue}`)
        })
        .height(this.selectHeight)
        .width(this.selectWidth)
        .borderWidth(1)
        .borderRadius(0)
        .margin({ left: 4 })
    }
  }
}

view文件夹下TextAndTextInput页面:

const TAG: string = 'cryptoToolbox'

// 文本 + 输入框组件
@Component
export struct TextAndTextInput {
  @Prop textValue: string
  fontSize?: number = 16
  @Link inputValue: string
  inputWidth: number = 0
  inputType?: InputType = InputType.Normal

  build() {
     view文件夹下TextAndTextInput页面:
      Text(this.textValue + ':')
        .fontSize(this.fontSize)
        .fontWeight(FontWeight.Bold)
        .textAlign(TextAlign.End)
        .margin({ right: 4 })

      TextInput({ text: this.inputValue, placeholder: this.textValue })
        .fontSize(this.fontSize)
        .borderRadius(0)
        .borderWidth(1)
        .height(35)
        .width(this.inputWidth)
        .margin({ right: 4 })
        .type(this.inputType)
        .onChange((value: string) => {
          this.inputValue = value
          console.log(TAG, `${this.textValue}: ${this.inputValue}`)
        })
    }
  }
}

viewmodel文件夹下Algorithm页面:

import CryptoJS from '@ohos/crypto-js'
import { SelectData } from '../comm/SelectData'
import { AlgorithmOption, AssignParamResult } from '../model/AlgorithmOption'
import { Cipher, HMAC, KeyDerivation, MD } from './AlgorithmImpl'

const TAG: string = 'cryptoToolbox== '

export default class Algorithm {
  static encrypt(option: AlgorithmOption): string {
    const result: AssignParamResult = Algorithm.assignParam(option)
    switch (result.algorithmTypeId) {
      case 0:
        return MD.hashEncrypt({
          hasherHelper: result.algorithm,
          plaintext: result.plaintext,
          encoding: result.encoding,
          outputLength: result.outputLength
        })
      case 1:
        return HMAC.hmacEncrypt({
          hmacHasherHelper: result.algorithm,
          plaintext: result.plaintext,
          secretKey: result.secretKey,
          encoding: result.encoding
        })
      case 2:
        return KeyDerivation.keyDerivationEncrypt({
          hasherStatic: result.algorithm,
          password: result.plaintext,
          salt: result.secretKey,
          keySize: result.keySize,
          iterations: result.iterations,
          encoding: result.encoding
        })
      case 3:
        return Cipher.CryptEncrypt({
          CipherHelper: result.algorithm,
          plaintext: result.plaintext,
          secretKey: result.secretKey,
          mode: result.mode,
          pad: result.pad,
          iv: result.iv,
          encoding: result.encoding
        })
      default:
        throw new Error('不支持的算法类型!')
    }
  }

  static decrypt(option: AlgorithmOption): string {
    const result: AssignParamResult = Algorithm.assignParam(option)
    return Cipher.CryptDecrypt({
      CipherHelper: result.algorithm,
      ciphertext: result.ciphertext,
      secretKey: result.secretKey,
      mode: result.mode,
      pad: result.pad,
      iv: result.iv,
      encoding: result.encoding
    })
  }

  static assignParam(algorithmOption: AlgorithmOption): AssignParamResult {
    console.log(TAG, 'algorithmOption: ' + JSON.stringify(algorithmOption))
    // 指定算法
    let algorithm: CryptoJS.HasherHelper | CryptoJS.HmacHasherHelper | CryptoJS.HasherStatic | CryptoJS.CipherHelper | undefined
      = SelectData.algorithmTypeData[algorithmOption.algorithmTypeId].data.get(algorithmOption.algorithm)

    // 指定分组模式
    let mode: CryptoJS.BlockCipherMode | undefined = SelectData.modeData.get(algorithmOption.mode)

    // 指定填充方式
    let pad: CryptoJS.Padding | undefined = SelectData.padData.get(algorithmOption.pad)

    // 指定编码方式
    let encoding: CryptoJS.Encoder | undefined = SelectData.encodingData.get(algorithmOption.encoding)

    // 返回结果
    return {
      algorithmTypeId: algorithmOption.algorithmTypeId,
      algorithm: algorithm,
      plaintext: algorithmOption.plaintext,
      ciphertext: algorithmOption.ciphertext,
      secretKey: algorithmOption.secretKey,
      mode: mode,
      pad: pad,
      encoding: encoding,
      iv: algorithmOption.iv,
      outputLength: parseInt(algorithmOption.outputLength),
      keySize: parseInt(algorithmOption.keySize),
      iterations: parseInt(algorithmOption.iterations)
    }
  }
}

viewmodel文件夹下AlgorithmImpl页面:

import CryptoJS from '@ohos/crypto-js'
import { CipherOption, HMACOption, KeyDerivationOption, MDOption } from '../model/AlgorithmOption'

const TAG: string = 'cryptoToolbox== '

// 消息摘要算法
export class MD {
  static hashEncrypt(option: MDOption): string {
    return option.hasherHelper(option.plaintext, { outputLength: option.outputLength }).toString(option.encoding)
  }
}

// 消息认证码算法
export class HMAC {
  static hmacEncrypt(option: HMACOption): string {
    const key: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse(option.secretKey)
    return option.hmacHasherHelper(option.plaintext, key).toString(option.encoding)
  }
}

// 密钥派生算法
export class KeyDerivation {
  static keyDerivationEncrypt(option: KeyDerivationOption): string {
    return CryptoJS.PBKDF2(option.password, option.salt, {
      keySize: option.keySize, // 密钥长度
      hasher: option.hasherStatic, // 哈希算法
      iterations: option.iterations // 迭代次数
    }).toString(option.encoding)
  }
}

// 加解密算法
export class Cipher {
  // 加密
  static CryptEncrypt(option: CipherOption): string {
    const plaintextArray: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse(option.plaintext)
    const secretKeyArray: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse(option.secretKey)
    const ivArray: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse(option.iv)
    return option.CipherHelper.encrypt(plaintextArray, secretKeyArray, {
      mode: option.mode,
      padding: option.pad,
      iv: ivArray
    }).ciphertext.toString(option.encoding)
  }

  // 解密
  static CryptDecrypt(option: CipherOption): string {
    if (option.encoding == CryptoJS.enc.Hex) {
      const ciphertextArray: CryptoJS.lib.WordArray = CryptoJS.enc.Hex.parse(option.ciphertext)
      option.ciphertext = CryptoJS.enc.Base64.stringify(ciphertextArray)
    }
    const secretKeyArray: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse(option.secretKey)
    const ivArray: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse(option.iv)
    return option.CipherHelper.decrypt(option.ciphertext, secretKeyArray, {
      mode: option.mode,
      padding: option.pad,
      iv: ivArray
    }).toString(CryptoJS.enc.Utf8)
  }
}
分享
微博
QQ
微信
回复
1天前
相关问题
HarmonyOS AES128|CBC|NoPadding 加密报错
56浏览 • 1回复 待解决
HarmonyOS AES CBC加密问题
607浏览 • 1回复 待解决
RSA NoPadding模式加密失败
1268浏览 • 1回复 待解决
aes-128加密问题如何实现?
236浏览 • 1回复 待解决
HarmonyOS SM4-ECB-NoPadding加密
61浏览 • 1回复 待解决
是否有AES的ECB模式加密算法
579浏览 • 1回复 待解决
HarmonyOS AES加密
24浏览 • 1回复 待解决
AES gcm模式加密有对应的库吗?
243浏览 • 1回复 待解决
HarmonyOS AES加密相关
30浏览 • 1回复 待解决
HarmonyOS RAS加密AES加密和解密
67浏览 • 1回复 待解决
HarmonyOS AES加密编码问题
83浏览 • 1回复 待解决
HarmonyOS 没找到 sm4 cbc 加密
23浏览 • 1回复 待解决
HarmonyOS AES加密算法demo
28浏览 • 1回复 待解决