1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include <iostream> #include <fstream> #include <string> #include <openssl/evp.h> #include <openssl/sha.h> #include <openssl/sm3.h>
std::string sm3_hash_string(const std::string& str) { unsigned char md[SM3_DIGEST_LENGTH]; SM3(reinterpret_cast<const unsigned char*>(str.data()), str.size(), md); std::string hash_str(reinterpret_cast<const char*>(md), SM3_DIGEST_LENGTH); return hash_str; }
std::string sm3_hash_file(const std::string& file_path) { unsigned char md[SM3_DIGEST_LENGTH]; std::ifstream input(file_path, std::ios::binary); if (input) { EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(mdctx, EVP_sm3(), nullptr); const size_t buf_size = 4096; char buf[buf_size]; while (input.read(buf, buf_size)) { EVP_DigestUpdate(mdctx, buf, buf_size); } size_t remain_size = input.gcount(); EVP_DigestUpdate(mdctx, buf, remain_size); EVP_DigestFinal_ex(mdctx, md, nullptr); EVP_MD_CTX_free(mdctx); input.close(); std::string hash_str(reinterpret_cast<const char*>(md), SM3_DIGEST_LENGTH); return hash_str; } else { throw std::runtime_error("fail to open file " + file_path); } }
void encrypt_file(const std::string& input_file_path, const std::string& output_file_path, const std::string& password) { std::ifstream input(input_file_path, std::ios::binary); std::ofstream output(output_file_path, std::ios::binary); if (input && output) { const int key_len = EVP_MAX_KEY_LENGTH; const int iv_len = EVP_MAX_IV_LENGTH; unsigned char key[key_len]; unsigned char iv[iv_len]; EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sm3(), nullptr, reinterpret_cast<const unsigned char*>(password.data()), password.size(), 1, key, iv); EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, iv); const size_t buf_size = 4096; char buf[buf_size]; while (input.read(buf, buf_size)) { int len = input.gcount(); int out_len = 0; EVP_EncryptUpdate(ctx, reinterpret_cast<unsigned char*>(buf), &out_len, reinterpret_cast<unsigned char*>(buf), len); output.write(buf, out_len); } int len = input.gcount(); int out_len = 0; EVP_EncryptFinal_ex(ctx, reinterpret_cast<unsigned char*>(buf), &out_len); output.write(buf, out_len); EVP_CIPHER_CTX_free(ctx); input.close(); output.close(); } else { throw std::runtime_error("fail to open input/output file."); }
}
int main() { std::string str = "message to be hashed"; std::cout << "SM3 hash of string \"" << str << "\": " << sm3_hash_string(str) << std::endl; std::string file_path = "test.txt"; std::cout << "SM3 hash of file \"" << file_path << "\": " << sm3_hash_file(file_path) << std::endl; std::string password = "123456"; try { encrypt_file(file_path, "test_encrypted.txt", password); } catch (const std::exception& e) { std::cout << "Error: " << e.what() << std::endl; } return 0; }
|