C++实现DES加密解密

来源:互联网 发布:程序员自我评价 编辑:程序博客网 时间:2024/05/20 20:46
#ifndef _DES_H_#define _DES_H_#include <string>#define BITS_PER_CHAR 8#define KEY_SZIE 8#define SUBKEY_NUM 16#define SUBKEY_LENGHT 48#define EXPAND_SIZE 48#define PC_2_SIZE 48#define PC_1_SIZE 56#define BIT_STR_SIZE 64class DES{public:DES();~DES();std::string Encrypt(const std::string& plain, const std::string& key);std::string Decrypt(const std::string& cipher, const std::string& key);private://生成16个子秘钥bool CreateSubKey(const std::string& key, char subKey[SUBKEY_NUM][SUBKEY_LENGHT]);//加密8字节数据块bool EncryptBlock(std::string& block, char subKey[SUBKEY_NUM][SUBKEY_LENGHT]);//解密8字节数据块bool DecryptBlock(std::string& block, char subKey[SUBKEY_NUM][SUBKEY_LENGHT]);private://----------------------------------转换工具-----------------------------------------------bool PC1_Transform(const std::string& bitStr, std::string& PC1BitStr);bool PC2_Transform(const std::string& PC1BitStr, char subKey[SUBKEY_LENGHT]);bool IP_Transform(std::string& bitStr);bool Expand_Transform(const std::string& halfBitStr, std::string& eBitStr);bool SBox_Transform(const std::string& eBitStr, std::string& halfBitStr);bool Permute_Transform(std::string& halfBitStr);bool IP_1_Transform(std::string& bitStr);private://------------------------------------基础工具------------------------------------------------bool Char8ToBit64(const std::string& str, std::string& bitStr);bool Bit64ToChar8(const std::string& bitStr, std::string& str);bool XOR(std::string& strFirst, std::string& strSecond, size_t num); bool LeftCycle(std::string& str, size_t beginSection, size_t endSection, size_t step);private://------------------------------------生成秘钥需要的表----------------------------------------//置换选择表1//压缩换位去掉每个字节的第8位,用作奇偶校检,基本上第8位可忽略static char PC1_Table[PC_1_SIZE];//左循环距离表static char Move_Table[SUBKEY_NUM];//置换选择表2//选择其中的某些位将其减少到48位static char PC2_Table[PC_2_SIZE];//----------------------------------加密或解密需要的表--------------------------------------------//初始置换表//表中的数值表示输入为被置换后的新位置static char IP_Table[BIT_STR_SIZE];//扩展表//通过重复某些位将32位的右半部分按照表扩展成48位static char Expand_Table[EXPAND_SIZE];//单纯置换表static char Permute_Table[BIT_STR_SIZE / 2];//反置换表static char IP_1_Table[BIT_STR_SIZE];//置换盒static char SBox_Table[KEY_SZIE][4][16];};#endif


#include "DES.h"//------------------------------------生成秘钥需要的表----------------------------------------char DES::PC1_Table[PC_1_SIZE] = {56,48,40,32,24,16,8,0,57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,60,52,44,36,28,20,12,4,27,19,11,3};char DES::Move_Table[SUBKEY_NUM] = {23,10,2,5,9,2,3,2,3,2,5,7,2,9,2,7};char DES::PC2_Table[PC_2_SIZE] = {13,16,10,23,0,4,2,27,14,5,20,9,22,18,11,3,25,7,15,6,26,19,12,1,40,51,30,36,46,54,29,39,50,44,32,46,43,48,38,55,33,52,45,41,49,35,28,31};//----------------------------------加密或解密需要的表--------------------------------------------char DES::IP_Table[BIT_STR_SIZE] = {57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,56,48,40,32,24,16,8,0,58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,46,38,30,22,14,6};char DES::Expand_Table[EXPAND_SIZE] = { 31, 0, 1, 2, 3, 4,3,  4, 5, 6, 7, 8,7,  8, 9,10,11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0};char DES::Permute_Table[BIT_STR_SIZE / 2] = {15, 6,19,20,28,11,27,16,0,14,22,25, 4,17,30, 9,1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24};char DES::IP_1_Table[BIT_STR_SIZE] = {39,7,47,15,55,23,63,31,38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25,32,0,40,8,48,16,56,24};char DES::SBox_Table[KEY_SZIE][4][16] = {//S1{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},{0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},{4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},{15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},//S2{{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},{3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},{0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},{13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},//S3{{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},{13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},{13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},{1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},//S4{{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},{13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},{10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},{3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},//S5{{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},{14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},{4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},{11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},//S6{{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},{10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},{9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},{4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},//S7{{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},{13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},{1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},{6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},//S8{{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},{1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},{7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},{2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};DES::DES(){}DES::~DES(){}std::string DES::Encrypt(const std::string& plain, const std::string& key){std::string result;if(plain.empty() || key.empty())return result;char subKey[16][48];if(!CreateSubKey(key, subKey))return result;for(size_t i = 0; i < plain.size() / 8; ++i){std::string block = plain.substr(i * 8, 8);EncryptBlock(block, subKey);result.append(block);}int remainder = plain.size() % 8;if(remainder){std::string block = plain.substr(plain.size() - remainder, remainder);block.append(8 - remainder, '\0');EncryptBlock(block, subKey);result.append(block);}return result;}std::string DES::Decrypt(const std::string& cipher, const std::string& key){std::string result;if(cipher.empty() || key.empty())return result;if(cipher.size() % 8)return result;char subKey[16][48];CreateSubKey(key, subKey);for(size_t i = 0; i < cipher.size() / 8; ++i){std::string block = cipher.substr(i * 8, 8);DecryptBlock(block, subKey);result.append(block);}return result;}bool DES::EncryptBlock(std::string& block, char subKey[SUBKEY_NUM][SUBKEY_LENGHT]){if(block.size() != KEY_SZIE)return false;std::string bitStr;bitStr.resize(BIT_STR_SIZE);Char8ToBit64(block, bitStr);IP_Transform(bitStr);std::string halfBitStr;halfBitStr.resize(bitStr.size() / 2);std::string eBitStr;eBitStr.resize(EXPAND_SIZE);for(size_t i = 0; i < SUBKEY_NUM; ++i){Expand_Transform(bitStr.substr(bitStr.size() / 2), eBitStr);XOR(eBitStr, std::string(subKey[i],SUBKEY_LENGHT), SUBKEY_LENGHT);SBox_Transform(eBitStr, halfBitStr);Permute_Transform(halfBitStr);XOR(bitStr, halfBitStr, halfBitStr.size());if(i != SUBKEY_NUM - 1)LeftCycle(bitStr, 0, bitStr.size(), bitStr.size() / 2);}IP_1_Transform(bitStr);Bit64ToChar8(bitStr, block);return true;}bool DES::DecryptBlock(std::string& block, char subKey[SUBKEY_NUM][SUBKEY_LENGHT]){if(block.size() != KEY_SZIE)return false;std::string bitStr;bitStr.resize(BIT_STR_SIZE);Char8ToBit64(block, bitStr);IP_Transform(bitStr);std::string halfBitStr;halfBitStr.resize(bitStr.size() / 2);std::string eBitStr;eBitStr.resize(EXPAND_SIZE);for(int i = SUBKEY_NUM - 1; i >= 0; --i){Expand_Transform(bitStr.substr(bitStr.size() / 2), eBitStr);XOR(eBitStr, std::string(subKey[i],SUBKEY_LENGHT), SUBKEY_LENGHT);SBox_Transform(eBitStr, halfBitStr);Permute_Transform(halfBitStr);XOR(bitStr, halfBitStr, halfBitStr.size());if(i != 0)LeftCycle(bitStr, 0, bitStr.size(), bitStr.size() / 2);}IP_1_Transform(bitStr);Bit64ToChar8(bitStr, block);return true;}bool DES::CreateSubKey(const std::string& key, char subKey[SUBKEY_NUM][SUBKEY_LENGHT]){std::string tmpKey(key);if(tmpKey.size() < KEY_SZIE)tmpKey.append(KEY_SZIE - tmpKey.size(), '\0');else if(tmpKey.size() > KEY_SZIE)tmpKey = tmpKey.substr(0, KEY_SZIE);std::string bitStr; bitStr.resize(BIT_STR_SIZE);// 64Char8ToBit64(tmpKey, bitStr);std::string PC1BitStr; PC1BitStr.resize(PC_1_SIZE);//56if(!PC1_Transform(bitStr, PC1BitStr))return false;for(int i = 0; i < SUBKEY_NUM; ++i){LeftCycle(PC1BitStr, 0, PC_1_SIZE / 2, Move_Table[i]);LeftCycle(PC1BitStr, PC_1_SIZE / 2, PC_1_SIZE, Move_Table[i]);PC2_Transform(PC1BitStr, subKey[i]); // 48}return true;}//-------------------------------------------------------------------------------------转换工具-----------------------------------------------bool DES::PC1_Transform(const std::string& bitStr, std::string& PC1BitStr){if(bitStr.size() != BIT_STR_SIZE || PC1BitStr.size() != PC_1_SIZE)return false;for(size_t i = 0; i < PC1BitStr.size(); ++i)PC1BitStr[i] = bitStr[PC1_Table[i]];return true;}bool DES::PC2_Transform(const std::string& PC1BitStr, char subKey[SUBKEY_LENGHT]){if(PC1BitStr.size() != PC_1_SIZE)return false;for(size_t i = 0; i < PC_2_SIZE; ++i)subKey[i] = PC1BitStr[PC2_Table[i]];return true;}bool DES::IP_Transform(std::string& bitStr){if(bitStr.size() != BIT_STR_SIZE)return false;std::string tmpBitStr;tmpBitStr.resize(bitStr.size());for(size_t i = 0; i < bitStr.size(); ++i)tmpBitStr[i] = bitStr[IP_Table[i]];bitStr.swap(tmpBitStr);return true;}bool DES::Expand_Transform(const std::string& halfBitStr, std::string& eBitStr){if(halfBitStr.size() != BIT_STR_SIZE / 2 || eBitStr.size() != EXPAND_SIZE)return false;for(size_t i = 0; i < eBitStr.size(); ++i)eBitStr[i] = halfBitStr[Expand_Table[i]];return true;}bool DES::SBox_Transform(const std::string& eBitStr, std::string& halfBitStr){if(eBitStr.size() != EXPAND_SIZE || halfBitStr.size() != BIT_STR_SIZE / 2)return false;for(size_t i = 0; i < KEY_SZIE; ++i){size_t j = i * 6;size_t row = (eBitStr[j] << 1) + eBitStr[j + eBitStr.size() / KEY_SZIE -1];size_t column = (eBitStr[j + 1] << 3) + (eBitStr[j + 2] << 2) + (eBitStr[j + 3] << 1) + eBitStr[j + 4];int x = SBox_Table[i][row][column];halfBitStr[i * 4] = x >> 3;halfBitStr[i * 4 + 1] = (x >> 2) & 0x1;halfBitStr[i * 4 + 2] = (x >> 1) & 0x1;halfBitStr[i * 4 + 3] = x & 0x1;}return true;}bool DES::Permute_Transform(std::string& halfBitStr){if(halfBitStr.size() != BIT_STR_SIZE / 2)return false;std::string tmpStr;tmpStr.resize(halfBitStr.size());for(size_t i = 0; i < halfBitStr.size(); ++i)tmpStr[i] = halfBitStr[Permute_Table[i]];halfBitStr.swap(tmpStr);return true;}bool DES::IP_1_Transform(std::string& bitStr){if(bitStr.size() != BIT_STR_SIZE)return false;std::string tmpStr;tmpStr.resize(BIT_STR_SIZE);for(size_t i = 0; i < bitStr.size(); ++i)tmpStr[i] = bitStr[IP_1_Table[i]];bitStr.swap(tmpStr);return true;}//-------------------------------------------------------------------------------------基础工具------------------------------------------------bool DES::Char8ToBit64(const std::string& str, std::string& bitStr){if(str.size() != KEY_SZIE || bitStr.size() != BIT_STR_SIZE)return false;for(size_t i = 0; i < str.size(); ++i){for(size_t j = 0; j < BITS_PER_CHAR; ++j)bitStr[i * BITS_PER_CHAR + j] = (str[i] >> j) & 0x1;}return true;}bool DES::Bit64ToChar8(const std::string& bitStr, std::string& str){if(bitStr.size() < BIT_STR_SIZE || str.size() != KEY_SZIE)return false;str = "";str.resize(KEY_SZIE);for(size_t i = 0; i < KEY_SZIE; ++i){for(size_t j = 0; j < BITS_PER_CHAR; ++j)str[i] |= bitStr[i * KEY_SZIE + j] << j;}return true;}bool DES::LeftCycle(std::string& str, size_t beginSection, size_t endSection, size_t step){if(endSection > str.size())return false;size_t tmpStep = step % (endSection - beginSection); std::string tmpStr = str.substr(beginSection + tmpStep, endSection - beginSection - tmpStep);tmpStr.append(str.substr(beginSection, tmpStep));for(size_t i = beginSection; i < endSection; ++i)str[i] = tmpStr[i - beginSection];return true;}bool DES::XOR(std::string& strFirst, std::string& strSecond, size_t num){if(strFirst.size() < num || strSecond.size() < num)return false;for(size_t i = 0; i < num; ++i)strFirst[i] ^= strSecond[i];return true;}


0 0
原创粉丝点击