问题
加密
输入:<plaintext> <key> <iv> 输出:<ciphertext> 例如 输入:<i love you, sunsiqi> <0123456789ABCDEF> <FEDCBA0123456789> 输出:<4e152ec964f73950dfc7a3d833bdaeffd6f0b8a727c13c29>
解密
输入:<ciphertext> <key> <iv> 输出:<plaintext> 例如 输入:<4e152ec964f73950dfc7a3d833bdaeffd6f0b8a727c13c29> <0123456789ABCDEF> <FEDCBA0123456789> 输出:<i love you, sunsiqi>
特性
- CFB模式不需要进行明文填充处理
明文与密文长度保持1:1对应
特性 CBC模式 CFB模式 是否需要填充 需要PKCS#7填充 无需填充 数据长度关系 密文长度是块大小的倍数 密文长度=明文长度 错误传播 影响整个块 只影响单个字节 典型应用场景 文件加密 实时通信 初始化向量要求 必须唯一且不可预测 必须唯一且不可预测
代码
头文件
#include <iostream> #include <string> #include <cctype> #include <cryptopp/des.h> #include <cryptopp/modes.h> #include <cryptopp/filters.h> #include <cryptopp/hex.h> #include <stdexcept>
加密
namespace SymCryptoUtilities { bool isValidHex(const std::string& hexStr) { if (hexStr.empty()) return false; for (char c : hexStr) { if (!std::isxdigit(c)) return false; } return true; } std::string hexDecode(const std::string& hexStr) { if (hexStr.length() % 2 != 0) { throw std::invalid_argument("Hex string must have even length"); } std::string decoded; CryptoPP::StringSource ss( hexStr, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)) ); return decoded; } std::string hexEncode(const std::string& data) { std::string encoded; CryptoPP::StringSource ss( data, true, new CryptoPP::HexEncoder( new CryptoPP::StringSink(encoded), false ) ); return encoded; } // DES-CFB加密函数 std::string desCFBEncrypt(const std::string& plaintext, const std::string& key, const std::string& iv) { try { // 参数验证 if (key.size() != CryptoPP::DES::DEFAULT_KEYLENGTH) { throw std::invalid_argument("Invalid key size. Expected 8 bytes"); } if (iv.size() != CryptoPP::DES::BLOCKSIZE) { throw std::invalid_argument("Invalid IV size. Expected 8 bytes"); } // 设置加密器 CryptoPP::CFB_Mode<CryptoPP::DES>::Encryption encryptor; encryptor.SetKeyWithIV( reinterpret_cast<const CryptoPP::byte*>(key.data()), key.size(), reinterpret_cast<const CryptoPP::byte*>(iv.data()), iv.size() ); // 执行加密 std::string ciphertext; CryptoPP::StringSource ss( plaintext, true, //流模式无需填充 new CryptoPP::StreamTransformationFilter( encryptor, new CryptoPP::StringSink(ciphertext)) //无填充参数 ); return hexEncode(ciphertext); } catch (const CryptoPP::Exception& e) { std::throw_with_nested(std::runtime_error("Crypto++错误: " + std::string(e.what()))); }catch (const std::exception& e) { std::cerr << "Standard Exception: " << e.what() << std::endl; throw; } } }
解密
namespace SymCryptoUtilities { bool isValidHex(const std::string& hexStr) { if (hexStr.empty()) return false; for (char c : hexStr) { if (!std::isxdigit(c)) return false; } return true; } std::string hexDecode(const std::string& hexStr) { if (hexStr.length() % 2 != 0) { throw std::invalid_argument("Hex string must have even length"); } std::string decoded; CryptoPP::StringSource ss( hexStr, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)) ); return decoded; } std::string hexEncode(const std::string& data) { std::string encoded; CryptoPP::StringSource ss( data, true, new CryptoPP::HexEncoder( new CryptoPP::StringSink(encoded), false ) ); return encoded; } // DES-CFB解密函数 std::string desCFBDecrypt(const std::string& ciphertextHex, const std::string& key, const std::string& iv) { try { // 参数验证 if (key.size() != CryptoPP::DES::DEFAULT_KEYLENGTH) { throw std::invalid_argument("Invalid key size. Expected 8 bytes"); } if (iv.size() != CryptoPP::DES::BLOCKSIZE) { throw std::invalid_argument("Invalid IV size. Expected 8 bytes"); } if (!isValidHex(ciphertextHex)) { throw std::invalid_argument("Invalid Hexadecimal ciphertext"); } // 解码十六进制 const std::string ciphertext = hexDecode(ciphertextHex); // 设置解密器 CryptoPP::CFB_Mode<CryptoPP::DES>::Decryption decryptor; decryptor.SetKeyWithIV( reinterpret_cast<const CryptoPP::byte*>(key.data()), key.size(), reinterpret_cast<const CryptoPP::byte*>(iv.data()), iv.size() ); // 执行解密 std::string decrypted; CryptoPP::StringSource ss( ciphertext, true, new CryptoPP::StreamTransformationFilter( decryptor, new CryptoPP::StringSink(decrypted) ) ); return decrypted; } catch (const CryptoPP::Exception& e) { std::throw_with_nested(std::runtime_error("Crypto++错误: " + std::string(e.what()))); }catch (const std::exception& e) { std::cerr << "Standard Exception: " << e.what() << std::endl; throw; } } }
主函数
int main(int argc, char* argv[]) { if (argc != 4) { if (argc != 4) { std::cerr << "Usage: " << argv[0] << " <plaintext> <hex_key> <hex_iv>\n" << "Example: " << argv[0] << " \"SecretData\" 0123456789ABCDEF FEDCBA9876543210\n" << "Note: Key and IV must be 16-character hexadecimal strings (8 bytes)\n" << "Note: support arbitrary binary data such as Chinese characters\n" << "Note: no padding is required when using the CFB mode." << std::endl; return 1; } } const std::string plaintext = argv[1]; const std::string keyHex = argv[2]; const std::string ivHex = argv[3]; try { // 输入验证 if (keyHex.length() != 16 || !SymCryptoUtilities::isValidHex(keyHex)) { throw std::invalid_argument("Key must be 16-character hex string (8 bytes)"); } if (ivHex.length() != 16 || !SymCryptoUtilities::isValidHex(ivHex)) { throw std::invalid_argument("IV must be 16-character hex string (8 bytes)"); } // 十六进制解码 const std::string key = SymCryptoUtilities::hexDecode(keyHex); const std::string iv = SymCryptoUtilities::hexDecode(ivHex); // 执行加密 const std::string ciphertext = SymCryptoUtilities::desCFBEncrypt(plaintext, key, iv); std::cout << "Ciphertext (hex): " << ciphertext << std::endl; } catch (const std::exception& e) { std::cerr << "Error: "; try { std::rethrow_if_nested(e); } catch (const std::exception& nested) { std::cerr << nested.what() << std::endl; return 2; } std::cerr << e.what() << std::endl; return 1; } return 0; }
运行
g++ DES64-CFB-decrypt.cpp -o decrypt -lcryptopp g++ DES64-CFB-encrypt.cpp -o encrypt -lcryptopp
测试