openssl + AES + c++ +cpuid
1 安装openssl
sudo apt-get update
sudo apt-get install openssl
sudo apt-get install libssl-dev
2 添加AES密码
# 生成 256 位的 AES 密钥
openssl rand -hex 32 > aes_key
# 生成 128 位的 IV
openssl rand -hex 16 > aes_iv
3 使用 AES 加密文档
# 加密文档
openssl enc -aes-256-cbc -salt -in plaintext.txt -out encrypted.aes -K $(cat aes_key) -iv $(cat aes_iv)
4 解密文档:
# 解密文档
openssl enc -aes-256-cbc -d -in encrypted.aes -out decrypted.txt -K $(cat aes_key) -iv $(cat aes_iv)
5 c++程序
#include <iostream>
#include <fstream>
#include <openssl/aes.h>
#include <openssl/rand.h>
// 解密函数
void decryptFile(const std::string& inputFileName, const std::string& outputFileName, const unsigned char* key, const unsigned char* iv) {
std::ifstream inputFile(inputFileName, std::ios::binary);
std::ofstream outputFile(outputFileName, std::ios::binary);
if (!inputFile.is_open() || !outputFile.is_open()) {
std::cerr << "Error opening files for decryption." << std::endl;
return;
}
AES_KEY decryptKey;
AES_set_decrypt_key(key, 256, &decryptKey);
const int blockSize = AES_BLOCK_SIZE;
unsigned char inputBuffer[blockSize];
unsigned char outputBuffer[blockSize];
while (inputFile.read(reinterpret_cast<char*>(inputBuffer), blockSize)) {
AES_decrypt(inputBuffer, outputBuffer, &decryptKey);
outputFile.write(reinterpret_cast<char*>(outputBuffer), blockSize);
}
inputFile.close();
outputFile.close();
}
int main() {
// 在实际应用中,密钥和 IV 应该从安全的地方获取
unsigned char key[32]; // 256位密钥
unsigned char iv[16]; // 128位IV
// 从文件中读取密钥和 IV
std::ifstream keyFile("aes_key", std::ios::binary);
std::ifstream ivFile("aes_iv", std::ios::binary);
if (!keyFile.is_open() || !ivFile.is_open()) {
std::cerr << "Error opening key or IV file." << std::endl;
return 1;
}
keyFile.read(reinterpret_cast<char*>(key), sizeof(key));
ivFile.read(reinterpret_cast<char*>(iv), sizeof(iv));
keyFile.close();
ivFile.close();
decryptFile("encrypted.aes", "decrypted.txt", key, iv);
std::cout << "Decryption complete." << std::endl;
return 0;
}
6查看CPUid
1)linux
//取消权限
sudo chmod +s /usr/sbin/dmidecode
//返回值大写,和windndows的cpu序列号顺序相反
dmidecode -t 4 | grep ID |sort -u |awk -F': ' '{print $2}'
代码
#include <stdio.h>
#include <iostream>
int main()
{
std::string ffmpegCommand = "sudo dmidecode -t 4 | grep ID |sort -u |awk -F': ' '{print $2}'";
FILE *ffmpegProcess = popen(ffmpegCommand.c_str(), "w");
if (!ffmpegProcess)
{
std::cerr << "Error opening ffmpeg process" << std::endl;
return EXIT_FAILURE;
}
pclose(ffmpegProcess);
return 0;
}
2) windows
命令行
wmic cpu get processorid
代码
#include <iostream>
#include <intrin.h> // 包含 __cpuid 函数
#include <sstream>
bool encryptWin() {
int cpu_info[4] = { -1 };
__cpuid(cpu_info, 0x00000001);
unsigned long long processor_id = static_cast<unsigned long long>(cpu_info[3]) << 32 | cpu_info[0];
std::cout << "Processor ID: " << std::hex << processor_id << std::endl;
long long decimalNumber = processor_id;
// 使用 std::stringstream 进行转换
std::stringstream ss;
ss << std::hex << decimalNumber;
// 从 stringstream 中获取十六进制字符串
std::string hexadecimalString = ss.str();
// 输出转换结果
//std::cout << "Decimal: " << decimalNumber << std::endl;
std::cout << "Hexadecimal: " << hexadecimalString << std::endl;
std::string cpuid = "178bfbff00a40f41";
if (cpuid == hexadecimalString) {
std::cout << "密码正确" << std::endl;
return true;
}
else
{
std::cout << "密码错误" << std::endl;
return false;
}
}
6 最终的工程函数
win下面的读取cpuid与比较,未使用AES加密
#include <iostream>
#include <intrin.h> // 包含 __cpuid 函数
#include <sstream>
bool encryptWin() {
int cpu_info[4] = { -1 };
__cpuid(cpu_info, 0x00000001);
unsigned long long processor_id = static_cast<unsigned long long>(cpu_info[3]) << 32 | cpu_info[0];
std::cout << "Processor ID: " << std::hex << processor_id << std::endl;
long long decimalNumber = processor_id;
// 使用 std::stringstream 进行转换
std::stringstream ss;
ss << std::hex << decimalNumber;
// 从 stringstream 中获取十六进制字符串
std::string hexadecimalString = ss.str();
// 输出转换结果
//std::cout << "Decimal: " << decimalNumber << std::endl;
std::cout << "Hexadecimal: " << hexadecimalString << std::endl;
std::string cpuid = "178bfbff00a40f41";
if (cpuid == hexadecimalString) {
std::cout << "密码正确" << std::endl;
return true;
}
else
{
std::cout << "密码错误" << std::endl;
return false;
}
}
linux下的使用了AES加密
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdio.h>
#include <algorithm>
using namespace std;
//AES解码的bash命令
std::string execute_command(const char *cmd) {
FILE *pipe = popen(cmd, "r");
if (!pipe) {
std::cerr << "Error executing command: " << cmd << std::endl;
return "";
}
char buffer[128];
std::string result = "";
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != nullptr)
result += buffer;
}
pclose(pipe);
return result;
}
//读取cpuid的命令
std::string readCPUID(){
std::string ffmpegCommand = "sudo dmidecode -t 4 | grep ID |sort -u |awk -F': ' '{print $2}'";
FILE *ffmpegProcess = popen(ffmpegCommand.c_str(), "r");
if (!ffmpegProcess)
{
std::cerr << "Error opening ffmpeg process" << std::endl;
return "failed to seek id";
}
char buffer[128];
std::string result = "";
while (!feof(ffmpegProcess)) {
if (fgets(buffer, 128, ffmpegProcess) != nullptr)
result += buffer;
}
std::cout<<" "<<result<<std::endl;
pclose(ffmpegProcess);
return result;
}
int main() {
// std::string key_command = "cat ../aes_key";
// std::string iv_command = "cat ../aes_iv";
std::string key_command = "567d7acc9e1431c2d5b87f6e93ce915c28d273c4e8af247d5c9be76c76a5a71b";
std::string iv_command = "14a6e42607974ac7f618714e6707f414";
// std::string decrypt_command = "openssl enc -aes-256-cbc -d -in ../encrypted.aes -K $(" + key_command + ") -iv $(" + iv_command + ")";
std::string decrypt_command = "openssl enc -aes-256-cbc -d -in ../encrypted.aes -K " + key_command + " -iv " + iv_command ;
std::string decrypted_text = execute_command(decrypt_command.c_str());
if (!decrypted_text.empty())
{
std::cout << "Decrypted Text: " << decrypted_text << std::endl;
}
else
{
std::cerr << "Error during decryption" << std::endl;
}
std::string inputString = readCPUID();
inputString.erase(std::remove_if(inputString.begin(), inputString.end(), [](unsigned char c) { return std::isspace(c); }), inputString.end());//去空格
std::string substring = inputString.substr(0, 16);//取前16个字符
cout<<substring<<endl;
decrypted_text.erase(std::remove_if(decrypted_text.begin(), decrypted_text.end(), [](unsigned char c) { return std::isspace(c); }), decrypted_text.end());//去空格
cout<< decrypted_text<<endl;
#ifdef __linux__
if(substring ==decrypted_text ){
cout<<"密码匹配"<<endl;
return 1;
}
else{
cout<<"密码不匹配"<<endl;
return 0;
}
#endif
#ifdef _WIN3232位 and 64位系统都适用
if(substring ==decrypted_text ){
cout<<"密码匹配"<<endl;
return 1;
}
else{
cout<<"密码不匹配"<<endl;
return 0;
}
#endif
}