#pragma once #include "squirrel.h" #include "sqstdaux.h" #include "sqstdblob.h" #include "sqstdio.h" #include "sqstdmath.h" #include "sqstdstring.h" #include "sqstdsystem.h" #include #include #include #include #include // 错误信息打印函数 void print_openssl_error() { char err_buf[256]; ERR_error_string_n(ERR_get_error(), err_buf, sizeof(err_buf)); std::cerr << "OpenSSL 错误: " << err_buf << std::endl; } // 生成 RSA 密钥对并保存到文件 // 生成 RSA 密钥对(公钥:X.509/PKCS#8 格式,私钥:PKCS#1 格式) bool generate_rsa_key(const std::string& pub_key_path, const std::string& pri_key_path, int key_bits = 2048) { // 1. 创建 RSA 对象并生成密钥对 RSA* rsa = RSA_new(); BIGNUM* bn = BN_new(); if (!rsa || !bn) { std::cerr << "创建 RSA/BIGNUM 失败" << std::endl; RSA_free(rsa); BN_free(bn); return false; } // 设置公钥指数(65537) if (BN_set_word(bn, RSA_F4) != 1) { std::cerr << "设置 BIGNUM 失败" << std::endl; print_openssl_error(); RSA_free(rsa); BN_free(bn); return false; } // 生成 RSA 密钥对 if (RSA_generate_key_ex(rsa, key_bits, bn, nullptr) != 1) { std::cerr << "生成 RSA 密钥对失败" << std::endl; print_openssl_error(); RSA_free(rsa); BN_free(bn); return false; } // 2. 封装 RSA 到 EVP_PKEY(用于生成 X.509/PKCS#8 公钥) EVP_PKEY* evp_key = EVP_PKEY_new(); if (!evp_key || EVP_PKEY_assign_RSA(evp_key, rsa) != 1) { std::cerr << "封装 EVP_PKEY 失败" << std::endl; print_openssl_error(); EVP_PKEY_free(evp_key); RSA_free(rsa); BN_free(bn); return false; } // 3. 保存 X.509/PKCS#8 格式公钥(-----BEGIN PUBLIC KEY-----) FILE* pub_file = fopen(pub_key_path.c_str(), "w"); if (!pub_file) { std::cerr << "打开公钥文件失败: " << pub_key_path << std::endl; EVP_PKEY_free(evp_key); BN_free(bn); return false; } if (PEM_write_PUBKEY(pub_file, evp_key) != 1) { std::cerr << "写入 X.509 公钥失败" << std::endl; print_openssl_error(); fclose(pub_file); EVP_PKEY_free(evp_key); BN_free(bn); return false; } fclose(pub_file); // 4. 保存 PKCS#1 格式私钥(-----BEGIN RSA PRIVATE KEY-----) FILE* pri_file = fopen(pri_key_path.c_str(), "w"); if (!pri_file) { std::cerr << "打开私钥文件失败: " << pri_key_path << std::endl; EVP_PKEY_free(evp_key); BN_free(bn); return false; } if (PEM_write_RSAPrivateKey(pri_file, rsa, nullptr, nullptr, 0, nullptr, nullptr) != 1) { std::cerr << "写入私钥失败" << std::endl; print_openssl_error(); fclose(pri_file); EVP_PKEY_free(evp_key); BN_free(bn); return false; } fclose(pri_file); // 5. 释放资源(EVP_PKEY_free 会自动释放内部的 RSA 对象) EVP_PKEY_free(evp_key); BN_free(bn); std::cout << "RSA 密钥生成成功!" << std::endl; std::cout << "公钥(X.509/PKCS#8 格式): " << pub_key_path << std::endl; std::cout << "私钥(PKCS#1 格式): " << pri_key_path << std::endl; return true; } static SQInteger Rsa_GenerateKey(HSQUIRRELVM v) { // 初始化 OpenSSL 错误处理 ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); // 生成 2048 位 RSA 密钥对(推荐使用 2048/4096 位) bool ret = generate_rsa_key("public.pem", "private.pem", 2048); // 清理 OpenSSL 资源 EVP_cleanup(); ERR_free_strings(); return 0; } // 从文件加载私钥(PKCS#1 格式) RSA* load_rsa_private_key(const std::string& pri_key_path) { FILE* pri_file = fopen(pri_key_path.c_str(), "r"); if (!pri_file) { std::cerr << "打开私钥文件失败: " << pri_key_path << std::endl; return nullptr; } // 加载 PKCS#1 格式私钥 RSA* rsa = PEM_read_RSAPrivateKey(pri_file, nullptr, nullptr, nullptr); fclose(pri_file); if (!rsa) { std::cerr << "加载私钥失败" << std::endl; print_openssl_error(); } return rsa; } // 新增:十六进制字符串转字节数组(核心补全) bool hex_string_to_bytes(const std::string& hex_str, std::vector& bytes) { bytes.clear(); // 检查长度是否为偶数(十六进制字符串必须2字符=1字节) if (hex_str.length() % 2 != 0) { std::cerr << "十六进制字符串长度为奇数,无效" << std::endl; return false; } for (size_t i = 0; i < hex_str.length(); i += 2) { std::string byte_str = hex_str.substr(i, 2); // 十六进制转字节(处理0-9/a-f/A-F) unsigned char byte = static_cast(strtol(byte_str.c_str(), nullptr, 16)); bytes.push_back(byte); } return true; } bool rsa_private_encrypt(const std::vector& plaintext_bytes, RSA* rsa_pri, std::string& ciphertext) { if (!rsa_pri || plaintext_bytes.empty()) return false; int rsa_len = RSA_size(rsa_pri); unsigned char* enc_buf = new unsigned char[rsa_len]; // 加密字节数组(而非字符串的ASCII) int enc_len = RSA_private_encrypt( plaintext_bytes.size(), // 明文长度(字节数) plaintext_bytes.data(), // 明文字节数组 enc_buf, // 加密结果缓冲区 rsa_pri, // RSA私钥 RSA_PKCS1_PADDING // 填充方式(和Java一致) ); if (enc_len > 0) { ciphertext = std::string((char*)enc_buf, enc_len); } else { std::cerr << "私钥加密失败(2048位RSA最多加密245字节)" << std::endl; print_openssl_error(); } delete[] enc_buf; return enc_len > 0; } static SQInteger Rsa_Private_Encrypt(HSQUIRRELVM v) { const SQChar* hex_str; sq_getstring(v, 2, &hex_str); // 获取Squirrel传入的十六进制字符串 // 1. 加载RSA私钥 RSA* rsa_pri = load_rsa_private_key("privatekey.pem"); if (!rsa_pri) { sq_pushnull(v); return 1; } // 2. 核心:十六进制字符串转字节数组(对齐Java的toByteArray) std::vector plaintext_bytes; if (!hex_string_to_bytes(std::string(hex_str), plaintext_bytes)) { RSA_free(rsa_pri); sq_pushnull(v); return 1; } // 3. 加密字节数组 std::string ciphertext; bool success = rsa_private_encrypt(plaintext_bytes, rsa_pri, ciphertext); // 4. 返回加密后的字节串(Squirrel中以字符串形式承载二进制数据) if (success) { sq_pushstring(v, ciphertext.c_str(), ciphertext.length()); } else { sq_pushnull(v); } // 释放资源 RSA_free(rsa_pri); return 1; } // ====================== 辅助函数 - 注册Squirrel函数 ====================== static SQInteger register_Rsa_func(HSQUIRRELVM v, SQFUNCTION f, const char* fname) { sq_pushroottable(v); sq_pushstring(v, fname, -1); sq_newclosure(v, f, 0); sq_newslot(v, -3, SQFalse); sq_pop(v, 1); // 弹出根表 return 0; } // ====================== 注册所有Dio函数 ====================== static void RegisterRsa(HSQUIRRELVM v) { register_Rsa_func(v, Rsa_GenerateKey, _SC("Sq_Rsa_GenerateKey")); //使用私钥签名 register_Rsa_func(v, Rsa_Private_Encrypt, _SC("Sq_Rsa_Private_Encrypt")); }