rand()引起的data abort

本文探讨了在使用DS-5编译器时遇到的dataabort bug,该问题源于rand()函数未通过srand()正确初始化。文章详细解释了如何避免此错误,并强调了初始化随机数生成器的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用rvct4.1编译,则rand()没有问题,使用ds-5编译,则出现data abort的bug,

最后发现是rand的初始化没有使用srand(),而是使用了_init_rand()造成的!!
2018.10.8

在运行命令g++ -o 1.exe 1.cpp -I"D:\software\OpenSSL-Win64\include" -L"D:\software\OpenSSL-Win64\lib\VC\x64\MT" -lcrypto -lssl -lws2_32编译后,运行1.exe程序报错: OPENSSL_Uplink(00007FFA8A905A28,08): no OPENSSL_Applink 我的代码如下: #include <openssl/rand.h> #include <openssl/evp.h> #include <openssl/ec.h> #include <openssl/pem.h> #include <openssl/err.h> #include <fstream> #include <vector> // 错误处理 void handleErrors() { ERR_print_errors_fp(stderr); abort(); } // 生成随机AES-256密钥 std::vector<unsigned char> generate_aes_key() { std::vector<unsigned char> key(32); // 256-bit if (RAND_bytes(key.data(), key.size()) != 1) handleErrors(); return key; } // 使用ECC公钥加密 std::vector<unsigned char> ecc_encrypt(EVP_PKEY* pubkey, const std::vector<unsigned char>& plaintext) { EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pubkey, nullptr); if (!ctx || EVP_PKEY_encrypt_init(ctx) <= 0) handleErrors(); size_t ciphertext_len; if (EVP_PKEY_encrypt(ctx, nullptr, &ciphertext_len, plaintext.data(), plaintext.size()) <= 0) handleErrors(); std::vector<unsigned char> ciphertext(ciphertext_len); if (EVP_PKEY_encrypt(ctx, ciphertext.data(), &ciphertext_len, plaintext.data(), plaintext.size()) <= 0) handleErrors(); EVP_PKEY_CTX_free(ctx); return ciphertext; } // AES-GCM加密 void aes_gcm_encrypt( const std::vector<unsigned char>& plaintext, const std::vector<unsigned char>& key, std::vector<unsigned char>& iv, std::vector<unsigned char>& ciphertext, std::vector<unsigned char>& tag ) { EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); iv.resize(12); // GCM推荐12字节IV RAND_bytes(iv.data(), iv.size()); if (EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, key.data(), iv.data()) != 1) handleErrors(); ciphertext.resize(plaintext.size() + EVP_MAX_BLOCK_LENGTH); int len; if (EVP_EncryptUpdate(ctx, ciphertext.data(), &len, plaintext.data(), plaintext.size()) != 1) handleErrors(); int ciphertext_len = len; if (EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len) != 1) handleErrors(); ciphertext_len += len; tag.resize(16); // GCM标签长度 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag.data()) != 1) handleErrors(); ciphertext.resize(ciphertext_len); EVP_CIPHER_CTX_free(ctx); } int main() { OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); // 加载ECC公钥 FILE* pubkey_file = fopen("public_key.pem", "r"); EVP_PKEY* pubkey = PEM_read_PUBKEY(pubkey_file, nullptr, nullptr, nullptr); fclose(pubkey_file); // 生成密钥 auto aes_key = generate_aes_key(); // 读取待加密文件 std::ifstream file("plain.txt", std::ios::binary); std::vector<unsigned char> file_data((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); // 执行加密 std::vector<unsigned char> iv, ciphertext, tag, encrypted_key; encrypted_key = ecc_encrypt(pubkey, aes_key); aes_gcm_encrypt(file_data, aes_key, iv, ciphertext, tag); // 保存加密结果 std::ofstream out("encrypted.bin", std::ios::binary); out.write(reinterpret_cast<char*>(encrypted_key.data()), encrypted_key.size()); out.write(reinterpret_cast<char*>(iv.data()), iv.size()); out.write(reinterpret_cast<char*>(tag.data()), tag.size()); out.write(reinterpret_cast<char*>(ciphertext.data()), ciphertext.size()); EVP_PKEY_free(pubkey); return 0; }
03-21
在运行命令g++ -o 1.exe 1.cpp -I"D:\software\OpenSSL-Win64\include" -L"D:\software\OpenSSL-Win64\lib\VC\x64\MT" -lcrypto -lssl -lws2_32编译后,运行1.exe程序报错: OPENSSL_Uplink(00007FFA8A905A28,08): no OPENSSL_Applink 我的代码如下: #include <openssl/rand.h> #include <openssl/evp.h> #include <openssl/ec.h> #include <openssl/pem.h> #include <openssl/err.h> #include <fstream> #include <vector> // 错误处理 void handleErrors() { ERR_print_errors_fp(stderr); abort(); } // 生成随机AES-256密钥 std::vector<unsigned char> generate_aes_key() { std::vector<unsigned char> key(32); // 256-bit if (RAND_bytes(key.data(), key.size()) != 1) handleErrors(); return key; } // 使用ECC公钥加密 std::vector<unsigned char> ecc_encrypt(EVP_PKEY* pubkey, const std::vector<unsigned char>& plaintext) { EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pubkey, nullptr); if (!ctx || EVP_PKEY_encrypt_init(ctx) <= 0) handleErrors(); size_t ciphertext_len; if (EVP_PKEY_encrypt(ctx, nullptr, &ciphertext_len, plaintext.data(), plaintext.size()) <= 0) handleErrors(); std::vector<unsigned char> ciphertext(ciphertext_len); if (EVP_PKEY_encrypt(ctx, ciphertext.data(), &ciphertext_len, plaintext.data(), plaintext.size()) <= 0) handleErrors(); EVP_PKEY_CTX_free(ctx); return ciphertext; } // AES-GCM加密 void aes_gcm_encrypt( const std::vector<unsigned char>& plaintext, const std::vector<unsigned char>& key, std::vector<unsigned char>& iv, std::vector<unsigned char>& ciphertext, std::vector<unsigned char>& tag ) { EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); iv.resize(12); // GCM推荐12字节IV RAND_bytes(iv.data(), iv.size()); if (EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, key.data(), iv.data()) != 1) handleErrors(); ciphertext.resize(plaintext.size() + EVP_MAX_BLOCK_LENGTH); int len; if (EVP_EncryptUpdate(ctx, ciphertext.data(), &len, plaintext.data(), plaintext.size()) != 1) handleErrors(); int ciphertext_len = len; if (EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len) != 1) handleErrors(); ciphertext_len += len; tag.resize(16); // GCM标签长度 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag.data()) != 1) handleErrors(); ciphertext.resize(ciphertext_len); EVP_CIPHER_CTX_free(ctx); } int main() { OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); // 加载ECC公钥 FILE* pubkey_file = fopen("public_key.pem", "r"); EVP_PKEY* pubkey = PEM_read_PUBKEY(pubkey_file, nullptr, nullptr, nullptr); fclose(pubkey_file); // 生成密钥 auto aes_key = generate_aes_key(); // 读取待加密文件 std::ifstream file("plain.txt", std::ios::binary); std::vector<unsigned char> file_data((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); // 执行加密 std::vector<unsigned char> iv, ciphertext, tag, encrypted_key; encrypted_key = ecc_encrypt(pubkey, aes_key); aes_gcm_encrypt(file_data, aes_key, iv, ciphertext, tag); // 保存加密结果 std::ofstream out("encrypted.bin", std::ios::binary); out.write(reinterpret_cast<char*>(encrypted_key.data()), encrypted_key.size()); out.write(reinterpret_cast<char*>(iv.data()), iv.size()); out.write(reinterpret_cast<char*>(tag.data()), tag.size()); out.write(reinterpret_cast<char*>(ciphertext.data()), ciphertext.size()); EVP_PKEY_free(pubkey); return 0; }
03-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值