1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16// [Start gcm_encrypt_decrypt_aes_symkey_sync] 17import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 18import { buffer } from '@kit.ArkTS'; 19 20function generateRandom(len: number) { 21 let rand = cryptoFramework.createRandom(); 22 let generateRandSync = rand.generateRandomSync(len); 23 return generateRandSync; 24} 25 26function genGcmParamsSpec() { 27 let ivBlob = generateRandom(12); 28 let arr = [1, 2, 3, 4, 5, 6, 7, 8]; // 8 bytes 29 let dataAad = new Uint8Array(arr); 30 let aadBlob: cryptoFramework.DataBlob = { data: dataAad }; 31 arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes 32 let dataTag = new Uint8Array(arr); 33 let tagBlob: cryptoFramework.DataBlob = { 34 data: dataTag 35 }; 36 // GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中 37 let gcmParamsSpec: cryptoFramework.GcmParamsSpec = { 38 iv: ivBlob, 39 aad: aadBlob, 40 authTag: tagBlob, 41 algName: 'GcmParamsSpec' 42 }; 43 return gcmParamsSpec; 44} 45 46let gcmParams = genGcmParamsSpec(); 47 48// 加密消息 49function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) { 50 let cipher = cryptoFramework.createCipher('AES128|GCM|PKCS7'); 51 cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams); 52 let encryptUpdate = cipher.updateSync(plainText); 53 // gcm模式加密doFinal时传入空,获得tag数据,并更新至gcmParams对象中。 54 gcmParams.authTag = cipher.doFinalSync(null); 55 return encryptUpdate; 56} 57 58// 解密消息 59function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) { 60 let decoder = cryptoFramework.createCipher('AES128|GCM|PKCS7'); 61 decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams); 62 let decryptUpdate = decoder.updateSync(cipherText); 63 // gcm模式解密doFinal时传入空,验证init时传入的tag数据,如果验证失败会抛出异常。 64 let decryptData = decoder.doFinalSync(null); 65 if (decryptData == null) { 66 console.info('GCM decrypt success, decryptData is null'); 67 } 68 return decryptUpdate; 69} 70 71function genSymKeyByData(symKeyData: Uint8Array) { 72 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 73 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 74 let symKey = aesGenerator.convertKeySync(symKeyBlob); 75 console.info('convertKeySync success'); 76 return symKey; 77} 78 79function main() { 80 let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); 81 let symKey = genSymKeyByData(keyData); 82 let message = 'This is a test'; 83 let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; 84 let encryptText = encryptMessage(symKey, plainText); 85 let decryptText = decryptMessage(symKey, encryptText); 86 if (plainText.data.toString() === decryptText.data.toString()) { 87 console.info('decrypt ok'); 88 console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8')); 89 } else { 90 console.error('decrypt failed'); 91 } 92} 93// [End gcm_encrypt_decrypt_aes_symkey_sync] 94 95@Entry 96@Component 97struct Index { 98 @State message: string = 'Encryption Decryption Guidance Aes ArkTs'; 99 100 build() { 101 Column({ space: 12 }) { 102 Text(this.message).fontSize(20).fontWeight(FontWeight.Bold) 103 Button($r('app.string.call_aes_gcm_synchronous')) 104 .width('70%') 105 .onClick(() => { 106 try { 107 main(); 108 this.message = 'AES_GCMSynchronousSuccess'; 109 } catch { 110 this.message = 'AES_GCMSynchronousFail'; 111 } 112 }) 113 } 114 .height('100%') 115 .width('100%') 116 } 117}