HarmonyOS 鸿蒙Next aes加密解密字符超出报错

HarmonyOS 鸿蒙Next aes加密解密字符超出报错

加密的文字超出16个字就报错了 // let message = this is a ttttttttttttt let message = this is a tttt  长的报错 短的不会

2 回复

HarmonyOS NEXT aes 加密 密文过长 需要使用分段加密 参考如下:

import { cryptoFramework } from '[@kit](/user/kit).CryptoArchitectureKit';

import { buffer } from '[@kit](/user/kit).ArkTS';

function genGcmParamsSpec() {

 let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes

 let dataIv = new Uint8Array(arr);

 let ivBlob: cryptoFramework.DataBlob = { data: dataIv };

 arr = [0, 0, 0, 0, 0, 0, 0, 0]; // 8 bytes

 let dataAad = new Uint8Array(arr);

 let aadBlob: cryptoFramework.DataBlob = { data: dataAad };

 arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes

 let dataTag = new Uint8Array(arr);

 let tagBlob: cryptoFramework.DataBlob = {

   data: dataTag

 }; // The GCM authTag is obtained by doFinal() in encryption and passed in params of init() in decryption.

 let gcmParamsSpec: cryptoFramework.GcmParamsSpec = {

   iv: ivBlob,

   aad: aadBlob,

   authTag: tagBlob,

   algName: "GcmParamsSpec"

 };

 return gcmParamsSpec;

}

let gcmParams = genGcmParamsSpec();

// 分段加密消息

function encryptMessageUpdateBySegment(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {

 let cipher = cryptoFramework.createCipher('AES128|GCM|PKCS7');

 cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams);

 let updateLength = 20; // 假设以20字节为单位进行分段update,实际并无要求

 let cipherText = new Uint8Array();

 for (let i = 0; i < plainText.data.length; i += updateLength) {

   let updateMessage = plainText.data.subarray(i, i + updateLength);

   let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };

   // 分段update

   let updateOutput = cipher.updateSync(updateMessageBlob);

   // 把update的结果拼接起来,得到密文(有些情况下还需拼接doFinal的结果,这取决于分组模式

   // 和填充模式,本例中GCM模式的doFinal结果只包含authTag而不含密文,所以不需要拼接)

   let mergeText = new Uint8Array(cipherText.length + updateOutput.data.length);

   mergeText.set(cipherText);

   mergeText.set(updateOutput.data, cipherText.length);

   cipherText = mergeText;

 }

 gcmParams.authTag = cipher.doFinalSync(null);

 let cipherBlob: cryptoFramework.DataBlob = { data: cipherText };

 return cipherBlob;

}

// 分段解密消息

function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {

 let decoder = cryptoFramework.createCipher('AES128|GCM|PKCS7');

 decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams);

 let updateLength = 20; // 假设以20字节为单位进行分段update,实际并无要求

 let decryptText = new Uint8Array();

 for (let i = 0; i < cipherText.data.length; i += updateLength) {

   let updateMessage = cipherText.data.subarray(i, i + updateLength);

   let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };

   // 分段update

   let updateOutput = decoder.updateSync(updateMessageBlob);

   // 把update的结果拼接起来,得到明文

   let mergeText = new Uint8Array(decryptText.length + updateOutput.data.length);

   mergeText.set(decryptText);

   mergeText.set(updateOutput.data, decryptText.length);

   decryptText = mergeText;

 }

 let decryptData = decoder.doFinalSync(null);

 if (decryptData == null) {

   console.info('GCM decrypt success, decryptData is null');

 }

 let decryptBlob: cryptoFramework.DataBlob = { data: decryptText };

 return decryptBlob;

}

async function genSymKeyByData(symKeyData: Uint8Array) {

 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };

 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');

 let symKey = await aesGenerator.convertKey(symKeyBlob);

 console.info('convertKey success');

 return symKey;

}

async function main() {

 let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);

 let symKey = await genSymKeyByData(keyData);

 let message = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; // 假设信息总共43字节,根据utf-8解码后,也是43字节

 let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };

 let encryptText = encryptMessageUpdateBySegment(symKey, plainText);

 let decryptText = decryptMessage(symKey, encryptText);

 if (plainText.data.toString() === decryptText.data.toString()) {

   console.info('decrypt ok');

   console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));

 } else {

   console.error('decrypt failed');

 }

}

参考指南链接:【 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/crypto-aes-sym-encrypt-decrypt-gcm-by-segment-V5

希望我的答复可以解决您遇到的问题 期待您的回复 蟹蟹

这里验证不存在超过16个字节加密失败的问题 请参考我的加解密demo实例 明文为71字节

输出如下:

encryptText: text64 vDzat+EcLsrElIhplzR8MZ8QQdY2+SRo80lMW86Udl+fEEHWNvkkaPNJTFvOlHZfnxBB1jb5JGjzSUxbzpR2X8OcwsA85AvJQMGa2xH6hm4=

encryptText: text16 BC3CDAB7E11C2ECAC494886997347C319F1041D636F92468F3494C5BCE94765F9F1041D636F92468F3494C5BCE94765F9F1041D636F92468F3494C5BCE94765FC39CC2C03CE40BC940C19ADB11FA866E

this is a ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt

import { cryptoFramework } from '[@kit](/user/kit).CryptoArchitectureKit';

import { buffer, util } from '[@kit](/user/kit).ArkTS';

[@Entry](/user/Entry)()

[@Component](/user/Component)

struct AESEEBCrypto {

  [@State](/user/State) message: string = '点击开始';

  build() {

    Row() {

      Column() {

        Text(this.message)

          .fontSize(50)

          .fontWeight(FontWeight.Bold)

          .onClick(() => {

            aesECB()

          })

      }

      .width('100%')

    }

    .height('100%')

  }

}

const name:string = ""

// 加密消息

function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {

  let cipher = cryptoFramework.createCipher('AES128|ECB|PKCS7');

  cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null);

  let cipherData = cipher.doFinalSync(plainText);

  return cipherData;

}

// 解密消息

function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {

  let decoder = cryptoFramework.createCipher('AES128|ECB|PKCS7');

  decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, null);

  let decryptData = decoder.doFinalSync(cipherText);

  return decryptData;

}

async function genSymKeyByData(symKeyData: Uint8Array) {

  let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };

  let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');

  let symKey = await aesGenerator.convertKey(symKeyBlob);

  console.info('convertKey success');

  return symKey;

}

function uint8ArrayTo16(arr:Uint8Array) {

  // let arr = new Uint8Array([34, 22, 11, 34]);

  let str = buffer.from(arr).toString('hex')

  console.log(str) // 22160b22

  let str2 = str.toUpperCase()

  console.log(str2) // 22160B22

  return str2;

}

async function aesECB() {

  try {

    let base64 = new util.Base64Helper();

    let keyData = "ffaa622a942ba86b";

    let key16 = new Uint8Array (buffer.from(keyData, 'utf-8').buffer)

    let symKey = await genSymKeyByData(key16);

    let message = `this is a ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt`

    let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };

    let encryptText = encryptMessage(symKey, plainText);

    console.error('encryptText: ' + encryptText.data.toString());

    let text64 = base64.encodeToStringSync(encryptText.data)

    console.error('encryptText: text64  ' + text64);

    let text16 = uint8ArrayTo16(encryptText.data)

    console.error('encryptText: text16  ' + text16);

    let decryptText = decryptMessage(symKey, encryptText);

    console.info('decryptText: ' + decryptText.data.toString());

    console.info('decryptText: ' + buffer.from(decryptText.data).toString('utf-8'));

  } catch (error) {

    console.error(`AES ECB “${error}“, error code: ${error.code}`);

  }

}

更多关于HarmonyOS 鸿蒙Next aes加密解密字符超出报错的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next系统中,AES加密解密操作若遇到字符超出报错的问题,通常是由于输入数据的长度不符合AES算法的块大小要求(AES块大小为16字节)或者密钥管理不当导致的。

AES加密要求输入数据长度必须是块大小的整数倍,如果不是,则需要进行填充(Padding)处理。常见的填充方式有PKCS#5/PKCS#7等。请检查你的加密解密代码中是否已正确实现数据填充和去除填充的逻辑。

此外,密钥管理也是关键。确保使用的密钥长度符合AES标准(128位、192位或256位),并且密钥在加密和解密过程中保持一致。

如果错误依旧存在,可能是库的使用方式有误或存在其他底层问题。建议检查以下几点:

  1. 确保使用的加密库与HarmonyOS版本兼容。
  2. 查阅HarmonyOS官方文档,确认API使用无误。
  3. 检查是否有内存溢出或资源限制导致的问题。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。在那里,你可以获得更专业的技术支持和解决方案。

回到顶部