BIO
和 BUF_MEM
指针。以下是改进后的 Base64 编码函数,它使用 BUF_MEM
更明确地进行内存管理以避免报错:
#include <openssl/evp.h> #include <openssl/rand.h> #include <openssl/sha.h> #include <openssl/bio.h> #include <openssl/buffer.h> #include <string.h> #include <stdio.h> #include <stdlib.h> void handleErrors(void) { ERR_print_errors_fp(stderr); abort(); } void print_bytes(const char *label, const unsigned char *buf, int length) { printf("%s: ", label); for (int i = 0; i < length; i++) { printf("%02x", buf[i]); } printf("\n"); } // Base64 编码函数 char *base64_encode(const unsigned char *input, int length) { BIO *bmem, *b64; BUF_MEM *bptr; b64 = BIO_new(BIO_f_base64()); bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // 设置 Base64 编码时不添加换行符 BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); char *buff = (char *)malloc(bptr->length + 1); if (buff) { memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = '\0'; } BIO_free_all(b64); return buff; } // AES 加密函数 int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext) { EVP_CIPHER_CTX *ctx; int len; int ciphertext_len; if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv)) handleErrors(); if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) handleErrors(); ciphertext_len = len; if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors(); ciphertext_len += len; EVP_CIPHER_CTX_free(ctx); return ciphertext_len; } // 使用 SHA-256 进行哈希运算 void sha256(const char *data, size_t data_len, unsigned char *output) { SHA256_CTX ctx; if (!SHA256_Init(&ctx)) handleErrors(); if (!SHA256_Update(&ctx, data, data_len)) handleErrors(); if (!SHA256_Final(output, &ctx)) handleErrors(); } int main() { unsigned char plaintext[] = "Hello, NDK!"; print_bytes("Plaintext", plaintext, strlen((char *)plaintext)); unsigned char key[32]; // 256-bit 密钥 if (!RAND_bytes(key, sizeof(key))) { handleErrors(); } print_bytes("Key", key, sizeof(key)); unsigned char iv[16]; // 初始化向量 IV 大小为 16 bytes if (!RAND_bytes(iv, sizeof(iv))) { handleErrors(); } print_bytes("IV", iv, sizeof(iv)); unsigned char ciphertext[128]; int ciphertext_len = encrypt(plaintext, strlen((char *)plaintext), key, iv, ciphertext); print_bytes("Ciphertext", ciphertext, ciphertext_len); // Base64 编码密文 char *base64_ciphertext = base64_encode(ciphertext, ciphertext_len); if (base64_ciphertext) { printf("Base64 Encoded Ciphertext: %s\n", base64_ciphertext); // 进行 SHA-256 哈希运算 unsigned char hash_output[SHA256_DIGEST_LENGTH]; sha256(base64_ciphertext, strlen(base64_ciphertext), hash_output); print_bytes("SHA256", hash_output, SHA256_DIGEST_LENGTH); free(base64_ciphertext); // 释放内存 } else { fprintf(stderr, "Failed to encode Base64.\n"); } return 0; }
BIO_flush
确保所有数据都已被写入。BIO_get_mem_ptr
获取编码后的数据内存指针(BUF_MEM
结构),然后将数据复制到新的缓冲区中,并在最后添加空字符作为字符串的结尾,确保内存管理正确。你还需要在项目中配置 CMakeLists.txt 或 Android.mk 文件,以确保链接 OpenSSL 所需的库文件和头文件路径:
cmake_minimum_required(VERSION 3.4.1) add_library(your_library_name SHARED main.c) find_library(log-lib log) find_package(OpenSSL REQUIRED) include_directories(${OPENSSL_INCLUDE_DIR}) target_link_libraries(your_library_name ${log-lib} ${OPENSSL_LIBRARIES})
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := your_module_name LOCAL_SRC_FILES := main.c LOCAL_LDLIBS := -L/path/to/openssl/lib -lssl -lcrypto include $(BUILD_SHARED_LIBRARY)
标签: 来源:
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。