3DES文件加密程序

本文介绍了基于MFC实现的3DES文件加解密程序,详细讲解了DES加密算法背景,3DES的工作原理,并给出了加密流程图。代码已上传至GitHub,供参考学习。
摘要由CSDN通过智能技术生成

参照<<密码学引论>> 第二版 张焕国 王张宜编著这本书,用MFC编写的框架,实现的使用3DES对文件进行加解密的程序
转载请说明来源 : enjoy5512的博客 http://blog.csdn.net/enjoy5512


DES加密算法简介

  1977年1月,美国政府颁布:采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DESData Encryption Standard) 。
  目前在国内,随着三金工程尤其是金卡工程的启动,DES算法在POS、ATM、磁卡及智能卡(IC卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保密,如信用卡持卡人的PIN的加密传输,IC卡与POS间的双向认证、金融交易数据包的MAC校验等,均用到DES算法。
  DES算法的入口参数有三个:Key、Data、Mode。
  其中Key为8个字节共64位,是DES算法的工作密钥;
  Data也为8个字节64位,是要被加密或被解密的数据;
  Mode为DES的工作方式,有两种:加密或解密。
  DES算法是这样工作的:
  如Mode为加密,则用Key 去把数据Data进行加密, 生成Data的密码形式(64位)作为DES的输出结果;
  如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。
  在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。
  通过定期在通信网络的源端和目的端同时改用新的Key,便能更进一步提高数据的保密性,这正是现在金融交易网络的流行做法。

  

3DES简介

  3DES是DES加密算法的一种模式,它使用3条64位的密钥对数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法。
  3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。
  设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密表,这样,
  3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
  3DES解密过程为:P=Dk1((EK2(Dk3(C)))
  K1、K2、K3决定了算法的安全性,若三个密钥互不相同,本质上就相当于用一个长为168位的密钥进行加密。多年来,它在对付强力攻击时是比较安全的。若数据对安全性要求不那么高,K1可以等于K3。在这种情况下,密钥的有效长度为112位


3DES加密流程图

子密钥产生
这里写图片描述


16轮加密
这里写图片描述


3DES加解密
这里写图片描述


代码实现

(所有源码在我的github上可以得到github.com/whu-enjoy/3DES)

因为注释挺详细了,这里就不细说
下面是我作的一个函数调用图

这里写图片描述

其中对八字节的数据,调用EncryptBlock()三次
加密
这里写图片描述
解密
这里写图片描述
我的密钥一跟密钥三用的一样的

加解密的类的实现

/////////////////////////////////////////////////////////////////////////////
//  DES class used for Encrypt/Decrypt
class DES : public CDialog{
public:
    //公共静态成员数组
    static int s_ia56PC_1[56];             //子密钥产生算法中的PC1矩阵
    static int s_ia16MoveTimes[16];        //子密钥产生算法中的左移次数表
    static int s_ia48PC_2[48];             //子密钥产生算法中的PC2矩阵
    static int s_ia64IP[64];               //加密算法中的初始置换IP矩阵
    static int s_ia48E[48];                //加密算法中的扩展置换E矩阵
    static int s_ia8_4_16S_Box[8][4][16];  //加密算法中的S盒
    static int s_ia32P[32];                //加密算法中的P矩阵
    static int s_ia64IP_1[64];             //加密算法中的逆初始置换IP^-1矩阵

    int ia2_16_48K[2][16][48];             //子密钥

public:
    //程序说明开始
    //==================================================================================
    //  功能 : 将输入的无符号字符数组转化为相应的二进制,转换c_iCount个字节
    //  参数 : const unsigned char c_ucaByte[], int iaBin[], const int c_iCount
    //  (入口)  c_ucaByte   : 需要转换的无符号字符数组
    //          c_iCount   : 需要转换的字节数
    //  (出口)  iaBin : 转换后的二进制流,用整型数组保存结果
    //  返回 : 无
    //  主要思路 : 对每个字节循环八次,第j次循环左移j次,再将最高位提取出来,就能获取这个
    //             字节的八位上的所有数据
    //  调用举例 : unsigned char uca5Pwd[5] = "test";
    //             int ia32Bin[32];
    //             ByteToBin(uca5Pwd, ia32Bin, 4);
    //  日期 : 2016年5月30日 19:17:10(注释日期)
    //==================================================================================
    //程序说明结束
    void ByteToBin(const unsigned char c_ucaByte[], int iaBin[], const int c_iCount)
    {
        int i = 0;
        int j = 0;

        //循环转化c_iCount个字节
        for ( i = 0; i < c_iCount; i++) 
        {
            for(j = 0; j < 8; j++)  
            {
                //第j次循环时,左移j次,再检查最高位是否是1,如果是,则赋值为1,否则赋值为0
                if (0x80 == ((c_ucaByte[i]<<j)&0x80))
                {
                    iaBin[i*8+j] = 1;
                }
                else
                {
                    iaBin[i*8+j] = 0;
                }
            }
        } 
    }

    //程序说明开始
    //==================================================================================
    //  功能 : 将输入的二进制转化为相应的无符号字符数组,转换c_iCount个字节
    //  参数 : const int c_iaBin[], unsigned char ucaByte[], const int c_iCount
    //  (入口)  c_iaBin : 需要转换的二进制流
    //          c_iCount     : 需要转换的字节数
    //  (出口)  ucaByte       : 转换后的无符号字符数组
    //  返回 : 无
    //  主要思路 : 对每个字节循环八次,第j次循环将原来的值左移一位,并将新的值加到最低位
    //  调用举例 : unsigned char uca5Pwd[5] = "";
    //             int ia32Bin[32] = {0,0,1,1,0,0,0,1,0,0,1,1,0,0,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,0};
    //             BinToByte(ia32Bin, uca5Pwd, 4);
    //  日期 : 2016年5月30日 19:24:25(注释日期)
    //==================================================================================
    //程序说明结束
    void BinToByte(const int c_iaBin[], unsigned char ucaByte[], const int c_iCount)
    {
        int i = 0;
        int j = 0;

        //转换c_iCount个字节
        for ( i = 0; i < c_iCount; i++) 
        {
            for(j = 0; j < 8; j++)  
            {
                //每次将原来的值左移一位,并加上新提取的
                ucaByte[i] = ucaByte[i] * 2 + c_iaBin[i*8+j];
            }
        } 
    }

    //程序说明开始
    //==================================================================================
    //  功能 : 根据输入的第二个矩阵将第一个矩阵进行转换,转换的结果保存在第三个矩阵里,
    //         转换c_iCount个数据
    //  参数 : const int c_iaSource[], const int c_iaReplaceTable[]
    //         int iaReplaced[], const int c_iCount
    //  (入口)  c_iaSource         : 需要转换的矩阵
    //          c_iaDisplaceTable  : 转换参考矩阵
    //          c_iCount           : 需要转换的数据个数
    //  (出口)  iaReplaced         : 转换后的矩阵
    //  返回 : 无
    //  主要思路 : iaReplaced矩阵的第i个位置上的数是c_iaSource矩阵中
    //             第c_iaReplaceTable[i]个位置的数据
    //  调用举例 : int ia64Source[64] = {xxxxx};
    //             int ia48Replace[48] = {xxxx};
    //             int ia48Replaced[48] = {0};
    //             Replacement(ia64Source, ia48Replace, ia48Replaced, 48);
    //  日期 : 2016年5月30日 19:39:24(注释日期)
    //==================================================================================
    //程序说明结束
    void Replacement(const int c_iaSource[], const int c_iaReplaceTable[], int iaReplaced[], const int c_iCount)
    {
        int i = 0;

        //循环c_iCount次
        for (i = 0; i < c_iCount; i++)
        {
            //根据c_iaReplaceTable[]置换原表
            iaReplaced[i] = c_iaSource[c_iaReplaceTable[i]-1];
        }
    }

    //程序说明开始
    //==================================================================================
    //  功能 : 将输入矩阵里面的数据左移c_iCount次,用ia28Output保存左移后的结果
    //  参数 : const int c_ia28Input[28], int ia28Output[28], const int c_iCount
    //  (入口)  c_ia28Input        : 需要左移的数组
    //          c_iCount           : 需要左移的数据个数
    //  (出口)  ia28Output         : 左移后的数组
    //  返回 : 无
    //  主要思路 : 先将原数组前c_iCount个数据保存在局部变量i2Temp中,然后输出数组的
    //             前28-c_iCount数据左移c_iCount位,再将i2Temp中的数据接到输出数组中
    //             这样做的时候,输入数组盒输出数组可以是同一个数组,减少内存空间使用量
    //  调用举例 : int ia28C[28] = {xxxxx};
    //             LeftMove(ia28C, ia28C, 2);
    //  日期 : 2016年5月30日 19:49:46(注释日期)
    //==================================================================================
    
  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。 最早的定义了该算法的标准(ANS X9.52,1998年发布)将其描述为“三重数据加密算法(TDEA)”— 即为ANSI X3.92中定义的数据加密算法(DEA)的三次重复操作— 而完全没有使用术语“3DES”或“DES”。FIPS PUB 46-3(1999)定义了“三重数据加密算法”(TDEA),也使用了术语“Triple DES”和“DES”。该标准中互换的使用“数据加密算法”(DEA)和“DES”的概念,其中以此开始DES的定义: 数据加密标准(DES)应当包括下文中的数据加密算法(DES[4])与三重数据加密算法(TDEA,如ANSI X9.52中所描述的) NIST SP 800-67(2004,2008[5])主要使用术语TDEA,但也提到了“Triple DES(TDEA)”。ISO/IEC 18033-3(2005)使用“TDEA”,但其中提到: TDEA通称Triple DES(数据加密标准)。 没有一个定义了本算法的标准使用术语“3DES”。 3DESughhhg34465345556555678==算法== 3DES使用“密钥包”,其包含3个DES密钥,K1,K2和K3,均为56位(除去奇偶校验位)。加密算法为: 密文 = EK3(DK2(EK1(平文))) 也就是说,使用K1为密钥进行DES加密,再用K2为密钥进行DES“解密”,最后以K3进行DES加密。 而解密则为其反过程: 平文 = DK1(EK2(DK3(密文))) 即以K3解密,以K2“加密”,最后以K1解密。 每次加密操作都只处理64位数据,称为一块。 无论是加密还是解密,中间一步都是前后两步的逆。这种做法提高了使用密钥选项2时的算法强度,并在使用密钥选项3时与DES兼容。 密钥选项[编辑] 标准定义了三种密钥选项: 密钥选项1:三个密钥是独立的。 密钥选项2:K1和K2是独立的,而K3=K1 密钥选项3:三个密钥均相等,即K1=K2=K3 密钥选项1的强度最高,拥有3 x 56 = 168个独立的密钥位。 密钥选项2的安全性稍低,拥有2 x 56 = 112个独立的密钥位。该选项比简单的应用DES两次的强度较高,即使用K1和K2,因为它可以防御中途相遇攻击。 密钥选项3等同与DES,只有56个密钥位。这个选项提供了与DES的兼容性,因为第1和第2次DES操作相互抵消了。该选项不再为国家标准科技协会(NIST)所建议[6],亦不为ISO/IEC 18033-3所支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值