# 使用AES对称密钥(GCM模å¼ï¼‰åŠ 解密(C/C++) å¯¹åº”çš„ç®—æ³•è§„æ ¼è¯·æŸ¥çœ‹[å¯¹ç§°å¯†é’¥åŠ è§£å¯†ç®—æ³•è§„æ ¼ï¼šAES](crypto-sym-encrypt-decrypt-spec.md#aes)。 ## 在CMake脚本ä¸é“¾æŽ¥ç›¸å…³åŠ¨æ€åº“ ```txt target_link_libraries(entry PUBLIC libohcrypto.so) ``` ## å¼€å‘æ¥éª¤ **åŠ å¯†** 1. 调用[OH_CryptoSymKeyGenerator_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_create)ã€[OH_CryptoSymKeyGenerator_Generate](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_generate),生æˆå¯†é’¥ç®—法为AESã€å¯†é’¥é•¿åº¦ä¸º128ä½çš„对称密钥(OH_CryptoSymKey)。 如何生æˆAES对称密钥,开å‘者å¯å‚考下文示例,并结åˆ[对称密钥生æˆå’Œè½¬æ¢è§„æ ¼ï¼šAES](crypto-sym-key-generation-conversion-spec.md#aes)å’Œ[éšæœºç”Ÿæˆå¯¹ç§°å¯†é’¥](crypto-generate-sym-key-randomly-ndk.md)ç†è§£ï¼Œå‚考文档与当å‰ç¤ºä¾‹å¯èƒ½å˜åœ¨å…¥å‚差异,请在阅读时注æ„区分。 2. 调用[OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_create),指定å—符串å‚æ•°'AES128|GCM|PKCS7',创建对称密钥类型为AES128ã€åˆ†ç»„模å¼ä¸ºGCMã€å¡«å……模å¼ä¸ºPKCS7çš„Cipher实例,用于完æˆåŠ 解密æ“作。 3. 调用[OH_CryptoSymCipherParams_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_create)创建å‚数对象,调用[OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_setparam)è®¾ç½®å¯¹åº”çš„åŠ å¯†å‚数。 4. 调用[OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_init),设置模å¼ä¸ºåŠ 密(CRYPTO_ENCRYPT_MODEï¼‰ï¼ŒæŒ‡å®šåŠ å¯†å¯†é’¥ï¼ˆOH_CryptoSymKey)和GCM模å¼å¯¹åº”çš„åŠ å¯†å‚数(OH_CryptoSymCipherParams),åˆå§‹åŒ–åŠ å¯†Cipher实例。 5. 调用[OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_update),更新数æ®ï¼ˆæ˜Žæ–‡ï¼‰ã€‚ 当å‰å•æ¬¡update长度没有é™åˆ¶ï¼Œå¼€å‘者å¯ä»¥æ ¹æ®æ•°æ®é‡åˆ¤æ–如何调用update。 - 当数æ®é‡è¾ƒå°æ—¶ï¼Œå¯ä»¥åœ¨init完æˆåŽç›´æŽ¥è°ƒç”¨final。 - 当数æ®é‡è¾ƒå¤§æ—¶ï¼Œå¯ä»¥å¤šæ¬¡è°ƒç”¨update,å³åˆ†æ®µåŠ 解密。 6. 调用[OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_final),获å–åŠ å¯†åŽçš„æ•°æ®ã€‚ - 由于已使用updateä¼ å…¥æ•°æ®ï¼Œæ¤å¤„dataä¼ å…¥null。 - final输出结果å¯èƒ½ä¸ºnull,在访问具体数æ®å‰ï¼Œéœ€è¦å…ˆåˆ¤æ–结果是å¦ä¸ºnull,é¿å…产生异常。 7. 使用[OH_CryptoSymCipherParams_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_create)创建Params,使用[OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_setparam)设置authTag,作为解密的认è¯ä¿¡æ¯ã€‚ 在GCM模å¼ä¸‹ï¼Œéœ€è¦ä»ŽåŠ 密åŽçš„æ•°æ®ä¸å–出末尾16å—节,作为解密时åˆå§‹åŒ–的认è¯ä¿¡æ¯ã€‚示例ä¸authTagæ°å¥½ä¸º16å—节。 8. 调用[OH_CryptoSymKeyGenerator_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_destroy)ã€[OH_CryptoSymCipher_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_destroy)ã€[OH_CryptoSymCipherParams_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_destroy)销æ¯å„对象。 **解密** 1. 调用[OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_init),设置模å¼ä¸ºè§£å¯†ï¼ˆCRYPTO_DECRYPT_MODE),指定解密密钥(OH_CryptoSymKey)和GCM模å¼å¯¹åº”的解密å‚数(OH_CryptoSymCipherParams),åˆå§‹åŒ–解密Cipher实例。 2. 调用[OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_update),更新数æ®ï¼ˆå¯†æ–‡ï¼‰ã€‚ 3. 调用[OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_final),获å–解密åŽçš„æ•°æ®ã€‚ - AES GCM模å¼åŠ 解密示例如下: ```c++ #include "CryptoArchitectureKit/crypto_common.h" #include "CryptoArchitectureKit/crypto_sym_cipher.h" #include <string.h> static OH_Crypto_ErrCode doTestAesGcm() { OH_CryptoSymKeyGenerator *genCtx = nullptr; OH_CryptoSymCipher *encCtx = nullptr; OH_CryptoSymCipher *decCtx = nullptr; OH_CryptoSymKey *keyCtx = nullptr; OH_CryptoSymCipherParams *params = nullptr; Crypto_DataBlob outUpdate = {.data = nullptr, .len = 0}; Crypto_DataBlob decUpdate = {.data = nullptr, .len = 0}; uint8_t aad[8] = {1, 2, 3, 4, 5, 6, 7, 8}; uint8_t tag[16] = {0}; uint8_t iv[12] = {1, 2, 4, 12, 3, 4, 2, 3, 3, 2, 0, 4}; // iv使用安全éšæœºæ•°ç”Ÿæˆ Crypto_DataBlob ivData = {.data = iv, .len = sizeof(iv)}; Crypto_DataBlob aadData = {.data = aad, .len = sizeof(aad)}; Crypto_DataBlob tagData = {.data = tag, .len = sizeof(tag)}; Crypto_DataBlob tagOutPut = {.data = nullptr, .len = 0}; char *plainText = const_cast<char *>("this is test!"); Crypto_DataBlob msgBlob = {.data = (uint8_t *)(plainText), .len = strlen(plainText)}; // 生æˆå¯¹ç§°å¯†é’¥ OH_Crypto_ErrCode ret; ret = OH_CryptoSymKeyGenerator_Create("AES128", &genCtx); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymKeyGenerator_Generate(genCtx, &keyCtx); if (ret != CRYPTO_SUCCESS) { goto end; } // 设置å‚æ•° ret = OH_CryptoSymCipherParams_Create(¶ms); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_IV_DATABLOB, &ivData); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_AAD_DATABLOB, &aadData); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagData); if (ret != CRYPTO_SUCCESS) { goto end; } // åŠ å¯† ret = OH_CryptoSymCipher_Create("AES128|GCM|PKCS7", &encCtx); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipher_Init(encCtx, CRYPTO_ENCRYPT_MODE, keyCtx, params); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipher_Update(encCtx, &msgBlob, &outUpdate); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipher_Final(encCtx, nullptr, &tagOutPut); if (ret != CRYPTO_SUCCESS) { goto end; } // 解密 ret = OH_CryptoSymCipher_Create("AES128|GCM|PKCS7", &decCtx); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagOutPut); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipher_Init(decCtx, CRYPTO_DECRYPT_MODE, keyCtx, params); if (ret != CRYPTO_SUCCESS) { goto end; } ret = OH_CryptoSymCipher_Final(decCtx, &outUpdate, &decUpdate); if (ret != CRYPTO_SUCCESS) { goto end; } end: OH_CryptoSymCipherParams_Destroy(params); OH_CryptoSymCipher_Destroy(encCtx); OH_CryptoSymCipher_Destroy(decCtx); OH_CryptoSymKeyGenerator_Destroy(genCtx); OH_CryptoSymKey_Destroy(keyCtx); OH_Crypto_FreeDataBlob(&outUpdate); OH_Crypto_FreeDataBlob(&decUpdate); OH_Crypto_FreeDataBlob(&tagOutPut); return ret; } ```