鸿蒙Des 加密解密 C++版本

鸿蒙Des 加密解密 C++版本

参考文件

写文档的时候,现在的 API 主流版本可能还是 API15 及以上,des 加密算法是在 API20 的时候才加入的。但是 API20 预计升级也是在 2025.10 月以后了。当前用到了 DES 加密解密,因此还是需要想办法实现一下的。

而且当前需要的是一个把 so 库的版本,需要把 Des 加密算法使用 c++实现,并且打包到 so 库中。

本文主要介绍一下,如何实现 Des 加密解密的 c++ 版本。

cryptopp 库

当然肯定不是自己实现一套加解密算法,现在是用的 cryptoPP 库,cryptoPP 库是一个开源的加解密库,支持多种加解密算法,包括 DES、AES、RSA 等。

cryptopp 项目地址:gitcode.com/openharmony...

下载项目代码

base 复制代码
git clone https://gitcode.com/openharmony-sig/tpc_c_cplusplus.git

配置编译环境

下载 command line tools

developer.huawei.com/consumer/cn...

导出 OHOS_SDK 环境变量
base 复制代码
export OHOS_SDK=~/command-line-tools/sdk/default/openharmony
拷贝必要鸿蒙平台的 cmake

这个地方可能要根据自己的本地的 cmake 地址来修改路径

base 复制代码
cp command-line-tools/sdk/default/openharmony/native/build-tools/cmake/share/cmake-3.28/Modules/Platform/OHOS.cmake /opt/homebrew/Cellar/cmake/4.0.2/share/cmake/Modules/Platform/
进入到相应的编译工具文件夹
base 复制代码
cd tpc_c_cplusplus/lycium/Buildtools
解压工具链
base 复制代码
tar -zxvf toolchain.tar.gz
拷贝必要的编译工具
base 复制代码
cp toolchain/\* command-line-tools/sdk/default/openharmony/native/llvm/bin/
进入到

tpc_c_cplusplus/lycium

开始编译

./build cryptopp

之后产物就在 lycium/usr 目录下 cd tpc_c_cplusplus/lycium/usr

在之后就可以根据文档来引入相关的库来编译 cryptopp

接入到项目中

如果是新项目,可以选择模版的时候创建 c++模版,这次主要说一下如何在已有项目中接入 c++库;

创建相应的目录

在 src/main 的目录下创建 cpp 文件夹。

cpp 文件夹下包含以下文件/文件夹:

bash 复制代码
├── CMakeLists.txt // c++ cmake 编译文件
├── include // 头文件目录
├── napi_init.cpp // 同arkts交互的接口文件,一般逻辑都在这个地方
├── thirdparty // 第三方目录文件,刚才编译完的crypto的文件直接拷贝到这个地方
    ├── cryptopp
        ├── arm64-v8a
        ├── armeabi-v7a
├── types
    ├── libentry
        ├── Index.d.ts // 导出的so接口
        ├── oh-package.json5 // so的配置文件

CMakeLists.txt

bash 复制代码
# the minimum version of CMake.
cmake_minimum_required(VERSION 3.5.0)
project(Encrypt) // 可以改一个名字,不过影响不大

set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})

if(DEFINED PACKAGE_FIND_FILE)
    include(${PACKAGE_FIND_FILE})
endif()

include_directories(${NATIVERENDER_ROOT_PATH}
                    ${NATIVERENDER_ROOT_PATH}/include)

add_library(entry SHARED napi_init.cpp)
target_link_libraries(entry PUBLIC libace_napi.z.so)
target_link_libraries(entry PUBLIC libohcrypto.so)
target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so)

# 这个地方是 cryptopp 库的引入文件方式
#将三方库加入工程中
target_link_libraries(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/cryptopp/${OHOS_ARCH}/lib/libcryptopp.a)
#将三方库的头文件加入工程中
target_include_directories(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/cryptopp/${OHOS_ARCH}/include)

napi_init.cpp

实现了一个解密算法,加密算法稍微改改参数就可以了。

c 复制代码
#include "napi/native_api.h"
#include <iostream>
#include <random>
#include <ctime>
#include <string.h>
#include <cstring>
#include "hilog/log.h"
#include "cryptopp/des.h"
#include "cryptopp/rsa.h"
#include "cryptopp/cryptlib.h"
#include "cryptopp/base64.h"
#include "cryptopp/filters.h"
#include "cryptopp/modes.h"
#include "cryptopp/hex.h"
#include "cryptopp/osrng.h"
#include "cryptopp/config_int.h"

std::string hexDecode(const std::string& hexStr) {
    std::string decoded;
    CryptoPP::StringSource ss(
        hexStr, true,
        new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded))
    );
    return decoded;
}

std::string generate_random_alphanumeric_string() {
    const std::string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    const int length = 8; // 固定生成8位字符串
    std::string result;

    // 使用随机设备作为种子(更安全)[2,5](@ref)
    std::random_device rd;
    std::mt19937 generator(rd());
    std::uniform_int_distribution<size_t> distribution(0, charset.size() - 1);

    // 预分配空间以提高性能[5](@ref)
    result.reserve(length);
    for (int i = 0; i < length; ++i) {
        result += charset[distribution(generator)];
    }
    return result;
}

static napi_value doDesDecrypt(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2] = {nullptr};

    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);

    // 获取加密字符串
    size_t encrypted_length = 0;
    napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &encrypted_length);
    if (status != napi_ok) {
        return nullptr;
    }
    char* encryptedStr = new char[encrypted_length + 1];
    std::memset(encryptedStr, 0, encrypted_length + 1);
    status = napi_get_value_string_utf8(env, args[0], encryptedStr, encrypted_length + 1, &encrypted_length);
    if (status != napi_ok) {
        if (encryptedStr) {
            delete[] encryptedStr;
        }
        return nullptr;
    }

    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);

    size_t key_length = 0;
    napi_status status = napi_get_value_string_utf8(env, args[1], nullptr, 0, &key_length);
    if (status != napi_ok) {
        OH_LOG_ERROR(LOG_APP, "xxx get key failed");
        return nullptr;
    }

    char* keyStr = new char[key_length + 1];
    std::memset(keyStr, 0, key_length + 1);
    status = napi_get_value_string_utf8(env, args[1], keyStr, key_length + 1, &key_length);
    if (status != napi_ok) {
        if (keyStr) {
            delete[] keyStr;
        }
        OH_LOG_ERROR(LOG_APP, "xxx copy key failed");
        return nullptr;
    }

    CryptoPP::ECB_Mode<CryptoPP::DES>::Decryption decryptor;
    decryptor.SetKey(reinterpret_cast<const CryptoPP::byte*>(keyStr), key_length);

    std::string decrypted;
    CryptoPP::StringSource ss(
        hexDecode(encryptedStr), true,
        new CryptoPP::StreamTransformationFilter(
            decryptor,
            new CryptoPP::StringSink(decrypted)
        )
    );

    napi_value result = nullptr;
    status = napi_create_string_utf8(env, decrypted.data(), decrypted.size(), &result);
    if (status != napi_ok) {
        napi_throw_error(env, nullptr, "Failed to create UTF-8 string");
        return nullptr;
    }
    return result;
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        { "decrypt", nullptr, doDesDecrypt, nullptr, nullptr, nullptr, napi_default, nullptr},
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "entry",
    .nm_priv = ((void*)0),
    .reserved = { 0 },
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{
    napi_module_register(&demoModule);
}

Index.d.ts

导出相应的函数,如果在 napi_init.cpp 中保存一个全局变量,那么在导出的函数中也能够使用。

javacript 复制代码
export const decrypt: (encrypted: string, key: string) => string;

oh-package.json5

json 复制代码
{
  "name": "libentry.so",
  "types": "./Index.d.ts",
  "version": "1.0.0",
  "description": "Please describe the basic information."
}

build-profile.json

然后需要在模块的编译配置中增加如下配置:

json 复制代码
  "buildOption": {
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",
      "arguments": "",
      "cppFlags": "",
    }
  },

模块 package 依赖中增加 c++模块依赖

json 复制代码
  "dependencies": {
    "libentry.so": "file:./src/main/cpp/types/libentry"
  }

结束

这样基本上就完成了 c++模块的加密解密功能的实现,在 ts 中调用也比较方便。

javascript 复制代码
import libEntry from 'libentry.so' // libEntry 是随便起了个名字
let res = libEntry.decrypt('des加密串', 'des密钥')
相关推荐
前端世界1 小时前
HarmonyOS 设备自动发现与连接全攻略:从原理到可运行 Demo
华为·harmonyos
御承扬1 小时前
HarmonyOS NEXT系列之编译三方C/C++库
c语言·c++·harmonyos
无风听海1 小时前
HarmonyOS之module.json5功能详解
harmonyos·module.json5
HMS Core1 小时前
HarmonyOS SDK助力讯飞听见App能力建设
华为·harmonyos
xyccstudio4 小时前
鸿蒙动态共享包HSP
前端·harmonyos
HarmonyOS_SDK5 小时前
行程信息一眼掌握!铁路12306接入实况窗带来安心出行新体验
harmonyos
simple_lau8 小时前
鸿蒙开发中的弹窗方案对比
harmonyos·arkts·arkui
li理8 小时前
鸿蒙 ArkTS 状态管理全解析:从基础到实战,轻松掌握响应式开发
harmonyos
xq95279 小时前
鸿蒙next内购支付接入教程横空出世
harmonyos