MFC框架的DES文件加密机

项目GitHub地址:https://github.com/joliph/DES_File

TIPS:
1.选择 项目 属性,字符集哪里选择使用多字节字符集,不要用UNICODE字符集
2.项目在Windows 10 + VS2017 + X64 +Release下编译测试通过,非X64版本部分API接口可能不一样
3.肯定有BUG,后续有机会就修,暂时没发现
4.DES算法接口和上篇的算法部分有些许改动
5.CBC模式为外部实现,即DES算法部分只能做ECB模式,确实有点难受,但是能用
6.消息响应函数哪里确实代码风格有些杂乱…
7.加解密过后文件的MD5值可能会发生变化但是不影响使用,因为只是后面被我多加了几个0使其8字节对齐而已
8.CBC模式的初始秘钥为64位的1

界面确实有点丑…

UI

算法测试:
秘钥:“security”
明文:“computercomputer”
ECB加密后的密码:“3B6C72B2710EB5133B6C72B2710EB513”
CBC加密后的密码:“3B6C72B2710EB51339283610A256F03E”

加密算法效率分析:
测试1:23兆字节文件:ECB:4.484秒 CBC:4.971秒
测试2:230兆字节文件:ECB:22.271秒 CBC:24.718秒
ECB效率高于CBC,因为CBC有额外的异或操作,而且后期可以做多线程ECB模式加密,因为ECB可以可以多线程同步运算,而CBC不行

关键函数作用及简要说明

1.  DES_Key类的构造函数设计
接收参数:char Char_Key[8]
作用:生成16轮密钥
步骤:
        1.调用CharToBit将8个字节的密钥转换成64位
        2.调用Transform进行置换选择
        3.左右分组
        4.16轮循环左移
        5.每轮再进行置换选择生成16轮密钥
DES_Key::DES_Key(char Char_Key[8]) {
    CharToBit(Bit_Key, Char_Key);
    Transform(Bit_Key, Bit_Key, PC1_Table, 56);
    bool *C0 = &Bit_Key[0];
    bool *D0 = &Bit_Key[28];
    for (int i = 0; i < 16; i++) {
        RotateL(C0, LOOP_Table[i]);
        RotateL(D0, LOOP_Table[i]);
        Transform(Round_Key[i], Bit_Key, PC2_Table, 48);
    }
}
********************************************************************************
2.  Xor矩阵异或函数设计:
接收参数:位矩阵A ,位矩阵B,矩阵位个数
作用:将A矩阵和B矩阵逐位异或,结果更新A矩阵
void Xor(bool *InputA, const bool *InputB, int len) {
    for (int i = 0; i < len; i++) {
        InputA[i] = InputA[i] ^ InputB[i];
    }
}
********************************************************************************
3.  CharToBit字符转位矩阵函数设计
接收参数:位矩阵指针 ,字符串指针
作用:将8位字符串转换成64个位矩阵
关键:位测试运算
void CharToBit(bool *Output, const char *Input) {
    for (int i = 0; i<64; i++) {
        Output[i] = (Input[i / 8] << (i % 8)) & 0x80;
    }
}
********************************************************************************
4.  Transform置换选择函数设计
接受参数:输出位矩阵指针,输入位矩阵指针,置换表,置换个数
作用:DES加密中的置换选择操作
void Transform(bool *Output, bool *Input, const int *Table, int Tablelen) {
    bool temp[256];
    for (int i = 0; i < Tablelen; i++) {
        temp[i] = Input[Table[i] - 1];
    }
    memcpy(Output, temp, Tablelen);
}
********************************************************************************
5.  RotateL左移函数设计
接受参数:输入位矩阵,左移长度
作用:DES轮秘钥生成中的左移操作,将位矩阵整体循环左移len长度
void RotateL(bool *Input, int len) {
    bool temp[28];
    memcpy(temp, &Input[len], 28 - len);
    memcpy(&temp[28 - len], Input, len);
    memcpy(Input, temp, 28);
}
********************************************************************************
6.  S_func S盒代换函数设计
接受参数:输出位矩阵,输入位矩阵
作用:DES加密中的S盒替换的函数实现,将48位矩阵压缩成32位
void S_func(bool *Output, bool *Input) {
    for (int i = 0; i < 8; i++) {
        int row = 2 * Input[6 * i] + 1 * Input[6 * i + 5];
        int col = 8 * Input[6 * i + 1] + 4 * Input[6 * i + 2] + 2 * Input[6 * i + 3] + 1 * Input[6 * i + 4];
        int s_result = S_Box[i][row][col];
        for (int j = 0; j < 4; j++) {
            Output[4 * i + j] = (s_result << j) & 0x8;
        }
    }
}
********************************************************************************
7.  F_func F函数设计
接受参数:输入R0矩阵,输入密钥位矩阵
作用:DES加密中的F函数实现,将密钥和密文进行混合加密
    步骤:
1.  调用Transform置换选择
2.  调用Xor函数进行矩阵异或
3.  调用S盒函数进行S盒代换
4.  调用Transform置换选择
void F_func(bool *R, bool *Key) {
    bool Ex_R[48];
    Transform(Ex_R, R, E_Table, 48);
    Xor(Ex_R, Key, 48);
    S_func(R, Ex_R);
    Transform(R, R, P_Table, 32);
}
********************************************************************************
8.  Des_Run DES加密函数设计
接受参数:输入明文位矩阵,输入密钥实例,输入加密后的密文存放指针
作用:输入明文进行DES加密,结果写入密文存放矩阵
    步骤:
1.  调用Transform置换选择
2.  左右明文分离
3.  16轮加密循环
1.  F函数混合密钥加密
2.  矩阵异或
3.  S函数代换压缩
4.  调用Transform置换选择
void Des_Run(bool *Bit_Mingwen, DES_Key DES_Key,char *pNewFileBuf) {
    Transform(Bit_Mingwen, Bit_Mingwen, IP_Table, 64);
    bool *L0 = &Bit_Mingwen[0];
    bool *R0 = &Bit_Mingwen[32];
    for (int i = 0; i < 16; i++) {
        bool temp[32];
        memcpy(temp, R0, 32);
        F_func(R0, DES_Key.Round_Key[i]);
        Xor(R0, L0, 32);
        memcpy(L0, temp, 32);
    }
    bool temp[32];
    memcpy(temp, R0, 32);
    memcpy(R0, L0, 32);
    memcpy(L0, temp, 32);
    Transform(Bit_Mingwen, Bit_Mingwen, IPR_Table, 64);
    ShowResult(Bit_Mingwen, pNewFileBuf);
}
********************************************************************************
9.  Re_Des_Run DES解密函数设计
接受参数:输入密文位矩阵,输入密钥实例,输入加密后的明文存放指针
作用:输入明文进行DES解密,结果写入明文存放矩阵
    步骤:
5.  调用Transform置换选择
6.  左右明文分离
7.  16轮解密循环
4.  F函数混合密钥解密
5.  矩阵异或
6.  S函数代换压缩
8.  调用Transform置换选择
void Re_Des_Run(bool *Bit_Mingwen, DES_Key DES_Key, char *pNewFileBuf) {
    Transform(Bit_Mingwen, Bit_Mingwen, IP_Table, 64);
    bool *L0 = &Bit_Mingwen[0];
    bool *R0 = &Bit_Mingwen[32];
    for (int i = 0; i < 16; i++) {
        bool temp[32];
        memcpy(temp, R0, 32);
        F_func(R0, DES_Key.Round_Key[15-i]);
        Xor(R0, L0, 32);
        memcpy(L0, temp, 32);
    }
    bool temp[32];
    memcpy(temp, R0, 32);
    memcpy(R0, L0, 32);
    memcpy(L0, temp, 32);
    Transform(Bit_Mingwen, Bit_Mingwen, IPR_Table, 64);
    ShowResult(Bit_Mingwen, pNewFileBuf);
}
********************************************************************************
10. ShowResult结果显示函数设计
接受参数:输入64位密文位矩阵,输入加密后的明文存放指针
作用:将64位位矩阵转换成16进制存储在指针指向的内存中
void ShowResult(const bool Input[64],char *pNewFileBuf) {
    int Character[8];
    for (int i = 0; i<8; i++) {
        pNewFileBuf[i] = char(128 * Input[0 + i * 8] + 64 * Input[1 + i * 8] + 32 * Input[2 + i * 8] + 16 * Input[3 + i * 8] +8 * Input[4 + i * 8] + 4 * Input[5 + i * 8] + 2 * Input[6 + i * 8] + 1 * Input[7 + i * 8]);
    }
}
********************************************************************************
11. OnBnClickedChose文件选择消息响应按钮
作用:响应文件选择按钮,将文件读入内存,使文件按8位对齐
void CDESFileDlg::OnBnClickedChose(){
    CFileDialog dlg(TRUE, NULL, NULL,
        OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
        (LPCTSTR)_TEXT("All Files (*.*)|*.*||"), NULL);
    if (dlg.DoModal() == IDOK)
        FilePath = dlg.GetPathName();
    else
        return;
    UpdateData(FALSE);
    File_Handle = CreateFile(FilePath,
        GENERIC_READ | GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (File_Handle == INVALID_HANDLE_VALUE) {
        MessageBoxA("加载文件失败!","Error", MB_OK);
        File_Handle = NULL;
        return;
    }
    FileSize = GetFileSize(File_Handle, NULL);
    int need_add = 0;
    if(FileSize % 8 != 0){
        need_add = 8 - (FileSize % 8);
    }
    pFileBuf = new char[FileSize+ need_add];
    DWORD ReadSize = 0;
    ReadFile(File_Handle, pFileBuf, FileSize, &ReadSize, NULL);
    memset(pFileBuf + FileSize, 0, need_add * sizeof(char));
    FileSize += need_add;
    CloseHandle(File_Handle);
    File_Handle = NULL;
}
********************************************************************************
12. OnBnClickedEncrypt加密消息响应按钮
作用:响应加密按钮,调用DES加密函数对文件进行加密,将新文件写入磁盘
分支:ECB加密+CBC加密
void CDESFileDlg::OnBnClickedEncrypt(){
    UpdateData(TRUE);
    if (!Check()) {
        return;
    }
    char *Char_Key= (char*)CString_Key.GetBuffer(0);
    DES_Key Input_Key(Char_Key);
    int count = FileSize / 8;
    pNewFileBuf = new char[FileSize];
    for(int i=0;i<count;i++){
        bool Bit_Mingwen[64];
        CharToBit(Bit_Mingwen, pFileBuf);
        if (Ls_CBC && i != 0) {
            CBC_Xor(Bit_Mingwen,pFileBuf, pNewFileBuf-8);
        }
        Des_Run(Bit_Mingwen, Input_Key, pNewFileBuf);
        pFileBuf += 8;
        pNewFileBuf += 8;
    }
    pNewFileBuf -= count * 8;
    int n=FilePath.ReverseFind('.');
    CString NewFilePath = FilePath.Left(n+1);
    NewFilePath+="encrypted";
    HANDLE NewFile_Handle=CreateFile(NewFilePath,
        GENERIC_READ | GENERIC_WRITE, 0, NULL,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    DWORD WriteSize = 0;
    WriteFile(NewFile_Handle, pNewFileBuf, FileSize, &WriteSize, NULL);
    CloseHandle(NewFile_Handle);
    NewFile_Handle = NULL;
    MessageBoxA("加密完成", "Nice", NULL);
}
********************************************************************************
13. OnBnClickedDecrypt解密消息响应按钮
作用:响应解密按钮,调用DES解密函数对文件进行解密,将新文件写入磁盘
分支:ECB解密+CBC解密
void CDESFileDlg::OnBnClickedDecrypt(){
    UpdateData(TRUE);
    if (!Check()) {
        return;
    }
    char *Char_Key = (char*)CString_Key.GetBuffer(0);
    DES_Key Input_Key(Char_Key);
    int count = FileSize / 8;
    pNewFileBuf = new char[FileSize];
    for (int i = 0; i<count; i++) {
        bool Bit_Mingwen[64];
        CharToBit(Bit_Mingwen, pFileBuf);
        Re_Des_Run(Bit_Mingwen, Input_Key, pNewFileBuf);
        if (Ls_CBC && i != 0) {
            CBC_Xor(Bit_Mingwen, pNewFileBuf, pFileBuf-8);
            ShowResult(Bit_Mingwen, pNewFileBuf);
        }
        pFileBuf += 8;
        pNewFileBuf += 8;
    }
    pNewFileBuf -= count * 8;
    int n = FilePath.ReverseFind('.');
    CString NewFilePath = FilePath.Left(n + 1);
    NewFilePath += "decrypted";
    HANDLE NewFile_Handle = CreateFile(NewFilePath,
        GENERIC_READ | GENERIC_WRITE, 0, NULL,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    DWORD WriteSize = 0;
    WriteFile(NewFile_Handle, pNewFileBuf, FileSize, &WriteSize, NULL);
    CloseHandle(NewFile_Handle);
    NewFile_Handle = NULL;
    MessageBoxA("解密完成", "Nice", NULL);
}
********************************************************************************
14. Check信息完整性检测按钮
作用:响应解密按钮,检测信息是否完整
BOOL CDESFileDlg::Check() {
    if (CString_Key.GetLength() != 8) {
        MessageBoxA("密钥应为8位","Error",MB_ICONWARNING);
        return FALSE;
    }
    return TRUE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值