精华内容
下载资源
问答
  • DES算法程序逆向分析

    2021-04-27 15:48:01
    二、DES算法加密过程 1、基本结构 DES算法是一种分组加密算法,一次加密64bit明文,通过64位初始密钥生成16个48位子密钥,将明文进行初始置换后分为左右两组,每组32位。进行迭代加密时候,将右32位作为下一轮...

    DES算法程序逆向分析

    一、DES算法简介

    DES算法是对称加密算法中的一种,是一种常用的加密算法。

    二、DES算法加密过程

    1、基本结构

    DES算法是一种分组加密算法,一次加密64bit明文,通过64位的初始密钥生成16个48位的子密钥,将明文进行初始置换后分为左右两组,每组32位。进行迭代加密的时候,将右32位作为下一轮迭代的左32位,而左32位与密钥进行加密以后成为下一轮迭代的右32位。设初始明文为L0R0,经过16轮迭代后变成L16R16,逆转为R16L16,再进行最终置换,获得最后的密文。

    2、密钥生成

    其中每轮当中的密钥都是由初始密钥生成的,初始密钥先要进行置换选择1,通过置换选择1将密钥变成56位,然后分为左右两个部分,然后进行循环左移,循环左移的位数是确定的,按顺序分别是1122222212222221,每轮左移产生一个密钥,分别参与各轮迭代;经过左移的密钥再通过一个置换选择2,将56位的密钥变成48位,和R进入F函数进行加密

    3、F函数

    接下来是F函数
    F函数将R和密钥作为输入,然后输出32位;F函数先对R进行一个E扩展置换,将32位扩展至48位,然后和48位的密钥进行异或运算,将结果放进S盒进行计算,输出32位,最后进行一个P置换,位数不变,作为F函数的输出
    S盒的计算方法如下:将48位分成8段,每段6位,将各段中首尾两位和中间四位作为S盒的“横坐标”和“纵坐标”得到对应坐标处的数字并变成4位的二进制数字,这样就完成了从48位到32位的转换

    (以上图片全都找自百度百科,侵也不删(doge))

    二、DES算法程序逆向分析

    1.main函数的结构

    用IDA打开desnc.exe,点开main函数

    这段代码在初始化栈空间以后,代码将数据段的一段字符串"DE3_En1C"的不同段分别赋值给var_C和var_8这俩个变量,值分别是"DE3_En1C"和"En1C",另外两个变量var_4和var_2C分别赋值为空串和0,然后调用puts函数输出一段字符串"give me a string to encrypt:",然后用scanf接受输入的字符串,并用strlen获得输入字符串的长度存入eax当中,并和8进行比较,如果不等,直接结束程序

    如果输入字符串长度等于8,则继续main函数加密过程

    逐行分析
    第一块调用了两个函数,一个是get_subkey,调用时将var_C入栈,可以猜测var_C是初始密钥;然后调用encryption函数,很显然就是加密函数了,将var_28和Str变量带入,可以想到,这个var_28是通过get_subkey函数生成的大量密钥,并且这个加密函数的加密结果就放在变量var_28中
    下面是个循环,可以看到,一共循环8次,每次循环都对加密的结果进行一次检测(现在可以猜测8位是检测的基本单位,因为al是8位2进制),只要检测出错误就直接跳转到输出"Wrong!!"字符串,如果8次检测都正确,就输出"Good Job!!"字符串
    这是这个程序整体的运行逻辑,下面对密钥生成和明文加密的过程进行分析

    2.密钥生成

    我们点击get_subkey函数,进入函数内部

    这里调用了两个函数,一个byte2Bit,一个pc1_replace,前一个从名字看不出来是什么用,第二个可以看出是置换选择1,我们点进第一个函数看一看

    这里arg_8的值为10h,即16,即外循环16次,内循环8次,循环的就是这玩意

    这段的含义可以理解为为一个16x8的矩阵中的每一个元素赋值,赋值方式就是将变量的值右移7-var_8位然后和0x01进行与运算然后赋值给矩阵中的每个元素(每个元素占一个字节),最后的结果就是16个相同的由初始密钥生成的64比特密钥
    然后调用pc1_replace函数

    可以看出来,通过变量var_4循环56次,将生成的64位的密钥按照数据段的PC1_Table来进行置换,因为PC1_Table中的值都是从1开始的,所以需要置换时每个对应的值都要-1

    通过置换选择1,密钥变成56位
    之后进入循环生成密钥的过程

    这里调用了两次shift_left函数,因为已经将密钥分成了左右两个部分,左右分别进行循环左移,而循环左移的位数就在LOOP_Table当中存储着

    每次都是循环当前次数的值所对应的LOOP_Table值
    然后再调用pc2_replace函数,将合并后的56位转变成48位的密钥

    3.加密函数

    生成密钥以后,就要将它付诸实施,用于加密输入的明文信息
    因为接受了8个字节的信息,也就是64bit,正好是一个DES算法的一个分组,下面函数就是用来加密这串明文的
    首先点开encryption函数

    首先还是用byte2Bit将明文变成二进制数据,然后调用ip_replace进行IP置换

    IP置换和前面的置换原理相同,都是通过一个变换的矩阵循环赋值实现
    之后就开始16轮迭代

    这里看到循环次数是15,因为最后一轮迭代有一些别的操作需要做,前15轮是一样的
    这里首先调用F函数,将之前生成的密钥和明文的右32位进栈,我们点入F函数

    可以看到这是一个线性的过程,流程上看非常简单,就是先调用e_expand进行E扩展,然后调用byteXOR将明文和密文进行异或,可以看到最后一个参数的值为30H=48,即一共要对48位的每一位都进行异或;然后就是调用s_replace函数进行S盒置换,将48bit的信息通过非线性的方式变成32bit,最后再进行p置换,其中所有置换和扩展的过程都与pc1_replace类似,不再赘述
    详细了解一下S盒置换过程

    mov     ecx, [ebp+var_4]
    imul    ecx, 6
    mov     edx, [ebp+arg_0]
    xor     eax, eax
    mov     al, [edx+ecx]
    shl     eax, 1
    mov     ecx, [ebp+var_4]
    imul    ecx, 6
    mov     edx, [ebp+arg_0]
    xor     ebx, ebx
    mov     bl, [edx+ecx+5]
    or      eax, ebx
    and     eax, 3
    mov     [ebp+var_C], eax
    mov     eax, [ebp+var_4]
    imul    eax, 6
    mov     ecx, [ebp+arg_0]
    xor     edx, edx
    mov     dl, [ecx+eax+1]
    shl     edx, 3
    mov     eax, [ebp+var_4]
    imul    eax, 6
    mov     ecx, [ebp+arg_0]
    xor     ebx, ebx
    mov     bl, [ecx+eax+2]
    shl     ebx, 2
    or      edx, ebx
    mov     eax, [ebp+var_4]
    imul    eax, 6
    mov     ecx, [ebp+arg_0]
    xor     ebx, ebx
    mov     bl, [ecx+eax+3]
    shl     ebx, 1
    or      edx, ebx
    mov     eax, [ebp+var_4]
    imul    eax, 6
    mov     ecx, [ebp+arg_0]
    xor     ebx, ebx
    mov     bl, [ecx+eax+4]
    or      edx, ebx
    and     edx, 0Fh
    mov     [ebp+var_10], edx
    mov     edx, [ebp+var_4]
    shl     edx, 6
    mov     eax, [ebp+var_C]
    shl     eax, 4
    mov     ecx, [ebp+var_10]
    add     ecx, edx
    movsx   edx, ds:S_Box[eax+ecx]
    and     edx, 0Fh
    mov     [ebp+var_14], dl
    movsx   eax, [ebp+var_14]
    sar     eax, 3
    and     eax, 1
    mov     ecx, [ebp+arg_4]
    add     ecx, [ebp+var_8]
    mov     [ecx], al
    movsx   edx, [ebp+var_14]
    sar     edx, 2
    and     edx, 1
    mov     eax, [ebp+arg_4]
    add     eax, [ebp+var_8]
    mov     [eax+1], dl
    movsx   ecx, [ebp+var_14]
    sar     ecx, 1
    and     ecx, 1
    mov     edx, [ebp+arg_4]
    add     edx, [ebp+var_8]
    mov     [edx+2], cl
    movsx   eax, [ebp+var_14]
    and     eax, 1
    mov     ecx, [ebp+arg_4]
    add     ecx, [ebp+var_8]
    mov     [ecx+3], al
    mov     edx, [ebp+var_8]
    add     edx, 4
    mov     [ebp+var_8], edx
    jmp     loc_401718
    

    (太长了不好截图)
    通过一系列手段将6位分为首尾和中间部分,将它作为S盒的输入参数,在盒中找到对应的数字变成二进制数据输出(太难了,实在分析不粗来,最后还是用了F5)
    回到加密函数中,后面将从F函数中出来的32位和左32位进行异或,并交换位置

    最后一次迭代和之前的不同如图

    多了一个P逆置换,并将二进制数据转化为ASCII码对应的字符串
    这样加密就完成了

    4.检验结果

    分析到 result 为输出值,因而去查看 result 的值,得到 0EFh, 34h, 0D4h, 0A3h, 0C6h, 84h, 0E4h, 23h,并且获取到私钥 key=”DE3_En1C”,解密得到明文"HarDd3s?",输入 exe 文件发现成功

    三、总结

    DES算法虽然是对称加密算法,但在分析时依然有很多难懂的地方需要反复咀嚼消化,比如S盒的置换代码

    展开全文
  • DES 加密算法;3DES 加密算法;数据传输安全控制的基本要求;数据加密传输环境的基本要求;各层次密钥简介;密钥的产生;密钥保存示意图;PIN的加密和解密;PIN BLOCK ;PIN BLOCK;PIN的加密方法;联机报文 MAC 的计算方法 ;...
  • DES算法破解需要时间解析

    万次阅读 2016-11-08 18:11:11
    1.运用场景首先题目描述是这个样子:用DES算法加密一个64位明文,其中秘钥长度是56位。攻击者是知道明文和密文,但是不知道秘钥是什么。假设攻击者每一秒中能做1010次方个加密或者解密算法,现在给了...

    1.运用场景

    首先题目的描述是这个样子的:

    这里写图片描述

    用DES算法加密一个64位的明文,其中秘钥的长度是56位。攻击者是知道明文和密文的,但是不知道秘钥是什么。假设攻击者每一秒中能做10的10次方个加密或者解密算法,现在给了攻击者一个密文,要找出其配对的明文平均需要花费的时间是多少?


    这道题目我在批改的过程中发现基本上没有学生能够答对的,能写出正确的解题过程的学生我到现在还没有发现。

    没有把这道提做出来的主要原因,第一是真的不会做,第二没有理解题目的意思,概念不清楚。

    我们要花费的时间其实就是我们需要找出秘钥的时间。

    现在知道的就是一秒钟可以计算的可能性是10的10次方,现在我们要破解秘钥,总共是56位的二进制数,要找到这个秘钥我们平均需要尝试的次数是多少是解决这个问题的关键。

    下面我们就来详细的描述一下这道题目要怎么来解决。

    说明:如果你不幸也要做这道题,请你先自行尝试,不能得到正确答案再来参看解析,谢谢合作~



    2.解题思路

    这题要求解的是平均需要花费的时间。我们要算的是要找到这个秘钥平均需要花费的时间。现在秘钥总共是56位,那么破解这56位平均需要花费的时间是多少。就是这道题我们需要求解的问题。因为我们找到这个秘钥之后是可以很快的通过密文得到我们的明文的。

    我们先从简单的例子分析,然后来得到我们这道题的答案。

    假设我们秘钥就只有两位,那么我们需要猜几次。

    这里写图片描述

    由于有两位那么这个秘钥的可能就有四种可能。

    这里写图片描述

    分别是 0 0,0 1,1 0,11 这四种可能。那么我们可能一次就猜中了,这个是最好的情况,或者第一次没有猜中,第二次猜中;或者前两次都没有猜中,第三次猜中,或者是前三次都没有猜中,那么我们也知道秘钥是什么,就是剩余的那个。也就是最坏的情况下我们需要猜测3次,最坏的情况我们需要尝试3次,注意注意是三次。不是四次。
    我们需要猜测的次数:
    1
    2
    3
    那么平均数就是 (1+2+3)/3
    后面的个数表示有3个数,所以说如果秘钥的长度2那么我们平均猜测的次数就是6/3=2 就是两次就可以

    假设我们的秘钥是三个,那么秘钥的可能就有8种:
    0 0 0
    0 0 1
    0 1 0
    0 1 1
    1 0 0
    1 0 1
    1 1 0
    1 1 1

    假设我们就按照这个顺序来猜测,假设秘钥就是 0 0 0, 那么我们猜 0 0 0, 只用一次,这个是最好的情况。假设秘钥是 1 1 1, 我们按照我们刚才排列出来的顺序来猜测,发现猜了7次,你也没有猜中,那么我们也知道这个秘钥就是1 1 1,最后第8次是不需要尝试的,前7次尝试过后你也知道了秘钥的1 1 1.
    所以我们猜测的次数可能是:
    1
    2
    3
    4
    5
    6
    7
    那么我们平均需要猜测的次数就是(1+2+3+4+5+6+7)/7=4


    上面这个不就是个等差数列么,下面是需要猜测的次数的个数
    总共的个数有2n1

    等差数列前n项和公式 :

    Sn=n(a1+an)2

    在这里 n 就是 2n1 ; a1=1; an=2n1

    那么 a1+an=1+2n1=2n

    那么:Sn=2n(2n1)2

    刚好我们猜测的平均次数就是2n1 所以分子分母可以约分,我们就可以得到平均猜测的次数:2n1

    其实这道题到这里我们就已经做完了,那我们再来看看有没有其他的分析方法,或者更加简单。


    我们通过观察可以发现,最好的是一次,最差的情况是 2n1 次。 次好的情况是2次,比最差好一点的是2n2

    这个有一种“对称”的味道在里面,所以平均值就是最好次数和最差的情况的中值。 也就是 (1+2n1)2=2n2=2n1


    3.解答过程

    这里写图片描述

    这道题的解答过程如上面这个图所示。那如果题目是最多要猜测几次这个题目的解答过程就完全不一样了,最多我们需要猜测2n1 次我们一定是可以知道秘钥。所以在看题目的时候一定要注意关键字。


















    这里写图片描述




    这里写图片描述

    你还是要幸福
    你千万别招惹别人哭
    明天开始这一切都结束




    展开全文
  • 一、 DES算法原理概述 预备知识 64位为一个分组,当成明文输入DES算法模型,输出...基本过程是换位和置换(根据置换矩阵) ​ 算法核心概要 总体结构 Feistel轮函数 子密钥生成 解密过程 ​ 信息空...

    一、 DES算法原理概述

    预备知识

    • 64位为一个分组,当成明文输入DES算法模型,输出同样长度64位的密文。

    • 对称加密,加密密钥也是解密密钥,密钥定义了加密过程。

    • 密钥构成:64位,每8位的最后一位用于奇偶校验,所以实际密钥长度为56位。

    • 基本过程是换位和置换(根据置换矩阵)

    算法核心概要

    • 总体结构

    • Feistel轮函数

    • 子密钥生成

    • 解密过程

    信息空间处理:

    1. 原始明文消息的处理:最后的分组不足64位时,填充的字节为缺失的字节数目。

    2. 明文分组结构:$M = m_1m_2…m_{64} , m_i ∈ {0, 1},i= 1…64 $

    3. 密文分组结构: $C = c_1c_2…c_{64} , c_i ∈ {0, 1},i= 1…64 $

    4. 密钥结构:$K = k_1k_2…k_{64} , k_i ∈ {0, 1},i= 1…64 $

    加密过程:

    64位原始密文M经IP初始置换得到IP(M)IP(M)

    IP(M)IP(M)经过16次迭代T1,T2...T16T_1, T_2... T_{16} 得到T16T15...T1IP(M)T_16T_15...T_1IP(M)

    然后在经过IP1IP^{-1} 逆变换得到密文。

    解密过程:

    加密逆向进行分析。和加密不同的是,子密钥调度过程为逆序,其他一致。

    初始置换:

    给定一个固定的初始置换IP矩阵来重排明文块M中的二进制位。得到二进制串M0=IP(M)=L0R0M_0 = IP (M) = L_0R_0

    表: IP置换表(8 * 8)(row * col 下同)

    迭代T

    1. 迭代规则:交叉迭代。Li=Ri1  Ri=Li1f(Ri1,Ki)L_i = R_{i-1} \,\, R_i = L_{i-1} \bigoplus f(R_{i - 1}, K_i). KiK_i为子密钥,长度为Ki ,fK_i\,, ffiestelfiestel 轮函数。

    2. 16次迭代后产生L16R16L_{16}R_{16}

    3. 左右交换输出$R_{16}L_{16}

    逆置换P1P^{-1} C=IP1(R16L16)C = IP^{-1}(R_{16}L_{16})

    表: 逆置换表(8 * 8)

    轮函数f(Ri1,Ki)f(R_{i-1}, K_i)

    密码函数f(R, K)接受两个输入:32 位的数据和 48 位的子密钥。然后:

    1. 通过表 E 进行扩展置换 (表),将输入的 32 位数据扩展为 48 位;

    2. 将扩展后的 48 位数据与 48 位的子密钥进行异或运算;

    3. 将异或得到的 48 位数据分成 8 个 6 位的块,每一个块通过对应的一个 S 表产生一个 4 位的输出。其中,每个 S 表都是 4 行 16 列。**具体的置换过程如下:**把 6 位输入中的第 1 位和第 6 位取出来行成一个两位的二进制数 x ,作为 Si 表中的行数(0~3);把 6 位输入的中间 4 位构成另外一个二进制数 y,作为 Si 表的列数(0~15);查出 Si 盒表(8 * 4 * 16 的矩阵)中 x 行 y 列所对应的整数,将该整数转换为一个 4 位的二进制数。

    4. 把通过 S 表置换得到的 8 个 4 位连在一起,形成一个 32 位的数据。然后将该 32 位数据通过表 P 进行置换(称为P-置换),置换后得到一个仍然是 32 位的结果数据,这就是f(R, K)函数的输出。

    三个表:E扩展置换表(8 * 6),S盒置换表(4 * 16),P-置换表(8 * 4)

    子密钥生成

    1. 对密钥K中的56个非校验位实现PC-1置换,得到C0D0C_0D_0,即置换后的前28位和后28位。

    2. Ci1Di1C_{i-1} D_{i-1} 分别进行循环左移操作,得到CiDiC_{i}D_{i},当i=12916i = 1,2,9,16时二进制串左移一个位置,否则左移两个位置。

    3. 对56位的CiDiC_iD_i 实行PC-2压缩置换,得到48位的KiK_i 。 然后i++i++

    4. 如果已经得到K16K_{16},密码调度结束,否则转步骤2.

      两个表:压缩置换表PC-1 PC-2

    二、 代码模块

    在这里插入图片描述
    整个算法的需要的函数如上图所示。

    核心函数展示和描述

    由于解密函数需要的模块基本与加密一致,所以不做呈现。

    #####加密总函数############################################################################
    # 1. 初始置换 2. 交叉迭代 3. 逆置换
    def Encryption(plainText, secretKey):
        if PRINT_FLAG == True: 
            print("> 开始加密64位明文")
        M = list(plainText)
        L0, R0 = InitialPermutation(M)
        RL = CrossIterationInEncryption(L0, R0, secretKey)
        cipherText = "".join(InversePermutation(RL))
        return cipherText
    ##############################################################################################
    
    ######表格置换函数###########################################################################
    """
        function: transfrom the binaryStr with the giver permutation table
        condition: len(binaryStr) == len(PermutationTable)
        return: the permutated binary List.
    """
    # 传入01字符串列表和置换表,返回置换结果
    def Permutation(binaryStr, PermutationTable):
        length = len(PermutationTable)
        PermutatedList = []
        for i in range(0, length):
            PermutatedList.extend(binaryStr[PermutationTable[i] - 1])
        return PermutatedList
    ############################################################################################
    
    #########加密过程的的交叉迭代####################################################################
    """
       function: make cross iteration on L0, R0 for 16 times
       input: L0--the front 32 bits of 64-bits plain text , R0--the back 32 bits of plain text
       return: R16--the back iterated 32-bits result, L16--the front iterated 32-bits result 
    """
    # 16次交叉迭代,返回RL列表用于逆置换。
    def CrossIterationInEncryption(L_0, R_0, SecretKey):
       if PRINT_FLAG == True: 
           print("> 正在进行加密过程的交叉迭代")
       R = ""
       L = ""
       tmp_R = R_0
       tmp_L = L_0
       sonKeyList = createSonKey(SecretKey)
       for i in range(1,17):
           L = tmp_R
           R = XOROperation(tmp_L,Feistel(tmp_R,sonKeyList[i - 1]))
           tmp_R = R
           tmp_L = L
       RL = R + L
       return RL 
    ##############################################################################################
    
    ####创建子密钥##################################################################################
    """
        function: create the 16 son keys with the given key
        return: sonKeysList: 16 son keys list
    """
    def createSonKey(SecretKey):
        # 提取密钥中的非校验位
        if PRINT_FLAG == True: 
            print("> 正在生成16个子密钥")
        str_56_bits_List = list(SecretKey)
        sonKeyList = []
        # 进行PC-1置换
        Temp_PC_1_PermutationResult_C_i_1, Temp_PC_1_PermutationResult_D_i_1 = PC_1_Permutation(str_56_bits_List) 
        C_i = []
        D_i = []     
        for i in range(1, 17):        
            # C_i-1 D_i-1
            # 计算C_i D_i
            # 循环左移
            if i == 1 or i == 2 or i == 9 or i == 16:
                C_i = shiftLeft(Temp_PC_1_PermutationResult_C_i_1, 1)
                D_i = shiftLeft(Temp_PC_1_PermutationResult_D_i_1, 1)
            else:
                C_i = shiftLeft(Temp_PC_1_PermutationResult_C_i_1, 2)
                D_i = shiftLeft(Temp_PC_1_PermutationResult_D_i_1, 2)
            CD = C_i + D_i
            # PC2压缩置换
            sonKey_i = PC_2_Permutation(CD)
            sonKeyList.append(sonKey_i)  
            Temp_PC_1_PermutationResult_C_i_1 = C_i
            Temp_PC_1_PermutationResult_D_i_1 = D_i
            if i == 16:
                break
        return sonKeyList
    ##############################################################################################
    
    
    #####Feistel 函数#############################################################################
    """
        function: Feistel function to create bit-stR_ing to permute with R_i -- a 32-bit stR_ing
        input: R_i_1--the (i-1)th back 32 bits string, K_i--the son secret key
        return: Feistel result (string type)
    """
    # 轮函数:1. E扩展置换; 2. 扩展结果和子密钥进行异或运算 3. 进行S盒6-4转换
    def Feistel(R_i_1, K_i):
        if PRINT_FLAG == True: 
            print("> 正在执行feistel轮函数")
        E_ExpandResult = E_Expand(R_i_1)
        xorResult = XOROperation(E_ExpandResult, K_i)
        str_32_bits = []
        for i in range(8):
            str_6_bits = xorResult[i * 6: i * 6 + 6]
            str_32_bits += S_Box_Transformation(str_6_bits, i + 1)
        return "".join(P_Permutation(str_32_bits))
    ##############################################################################################
    
    ####随机生成64位key,8个字符#####################################################################
    """
        return: a 64-bits (8 bytes) string as a secret key
    """
    def createSecrteKey():
        seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+=-"
        key = []
        for i in range(8):
            key.append(random.choice(seed))
        randomSecretKey = ''.join(key)
        return randomSecretKey
    ################################################################################################
    
    ##########8个字符的字符串转为ascii,然后转 0 1串####################################
    def ToBitString(string_8_char):
        strList = []
        for i in range(8):
            strList.append(str(int2bin(ord(string_8_char[i]), 8)))
        return "".join(strList)
    ##################################################################################
    
    ########64位bits转为8个ascci字符###################################################
    def ToAsciiChar(string_64_bits):
        strList = []
        bitList = list(string_64_bits)
        for i in range(8):
            if int("".join(bitList[i * 8: i * 8 + 8]), 2) < 8:
                continue
            # 八个bit一个处理单元,先转为10进制,然后转ascii,存入列表
            strList.append(chr(int("".join(bitList[i * 8: i * 8 + 8]), 2)))
        return "".join(strList)
    ##################################################################################
    
    ############ 加密过程和解密过程
    while True:
            text_8_bytes = PlainTextFile.read(8)  # 读取8个ascii字符
            if not text_8_bytes:
                print("读取明文文件到结尾啦")
                break
            if len(text_8_bytes) != 8:
                full_flag = False
              
            else:
                bitString = ToBitString(text_8_bytes) # 8个ascii字符转十进制int,然后再转为64位01
                # 加密
                encryptStr = Encryption(bitString, secretKeyBitString)
                # 加密结果写入文件
                CipherTextFile.write(str(ToAsciiChar(encryptStr)))
                # 解密
                decryptStr = Decryption(encryptStr, secretKeyBitString)
                # 解密结果写入文件 
                DecryptTextFile.write(str(ToAsciiChar(decryptStr)))
            if full_flag == False:  # 如果尾部字节不足8个,那么每个字节都填入缺失的字节数量
                NumOfLostBytes = 8 - len(text_8_bytes)
                bitStringList = []
                for i in range(len(text_8_bytes)):
                    bitStringList.append(int2bin(ord(text_8_bytes[i]), 8))
        
                full_8_bits = int2bin(NumOfLostBytes, 8)  # 填充的比特串
                # 填充的字节数 转为bitstring
                for i in range(NumOfLostBytes):
                    bitStringList.append(full_8_bits)
                bitString = "".join(bitStringList)  #补全64位分组
                 # 加密
                encryptStr = Encryption(bitString, secretKeyBitString)
                # 加密结果写入文件
                CipherTextFile.write(str(ToAsciiChar(encryptStr)))
                # 解密
                decryptStr = Decryption(encryptStr, secretKeyBitString)
                # 解密结果写入文件 
                DecryptTextFile.write(str(ToAsciiChar(decryptStr)))
      # 读取完整的8个字节分组字节,尾部填充8个字节,取值都为08
        if full_flag == True:
            zero_eight = "00001000"
            tmpList = []
            for i in range(8):
                tmpList.append(zero_eight)
            bitString = "".join(tmpList)
            # 加密
            encryptStr = Encryption(bitString, secretKeyBitString)
            # 加密结果写入文件
            CipherTextFile.write(str(ToAsciiChar(encryptStr)))
            # 解密
            decryptStr = Decryption(encryptStr, secretKeyBitString)
            # 解密结果写入文件 
            DecryptTextFile.write(str(ToAsciiChar(decryptStr)))  
    

    数据结构说明

    1. 明文,密文,解密后的数据

    从明文文件中读取8个ascii字符,存放在string结构中,然后再转换为64个ascii字符的0 1 字符串作为加密的明文。加密结果和解密结果也是转换为ascii字符串,存放在文件中。

    1. 加密解密过程的0 1 字符串数据

    在实际操作中,由于python中的string不支持赋值以及增删操作,所以通过python里的list即列表来存放字符串,通过list 方便的操作接口来执行加密解密。而string和list之间的转换方式也很简单,如下。

    List = list(str)    # string 转 list
    str = "".join(List) # list 转string
    

    三、运行说明

    在实际的运行过程中,本实验计划读取明文文件,随机生成密钥文件,然后将加密后的密文和解密后的结果保存文件中,可在代码文件中修改文件命名格式和路径.

    #########文件变量
    CIPHER_TEXT_FILE = "cipherText.txt"   #密文文件
    PLAIN_TEXT_FILE = "plainText.txt"     #明文文件
    SECRET_KEY_FILE = "secretKey.txt"     #密钥文件
    DECRYPT_TEXT_FILE = "decryptText.txt" #解密文
    

    每次从明文中读取8个字节的内容就转换位64个01字符串,然后对字符串进行加密,同时输出加密结果到控制台和加密文件中,加密之后,对密文进行执行解密,将解密结果输出到控制台和解密文件中。

    由于只对ascii字符进行转换,如果明文文件中出现中文或者其它非ascii字符那么解密结果仍会出现其他乱码文字。

    如果明文中出现中文,那么解密后的结果的中文位置将会出现乱码。

    四、完整源码

    代码仅供参考,见 gihub。

    展开全文
  • 在《DES算法及其在VC++ 6.0下的实现(上)》中主要介绍了DES算法的基本原理,下面让我们继续: 二.子密钥的生成 64比特的密钥生成16个48比特的子密钥。 子密钥生成过程具体解释如下: 64比特的密钥K,经过PC-...
     
    

    《DES算法及其在VC++ 6.0下的实现(上)》中主要介绍了DES算法的基本原理,下面让我们继续:

    二.子密钥的生成
    64比特的密钥生成16个48比特的子密钥。

    子密钥生成过程具体解释如下:
    64比特的密钥K,经过PC-1后,生成56比特的串。其下标如表所示:

    PC-1 57 49 41 33 25 17 9
    1 58 50 42 34 26 18
    10 2 59 51 43 35 27
    19 11 3 60 52 44 36
    63 55 47 39 31 23 15
    7 62 54 46 38 30 22
    14 6 61 53 45 37 29
    21 13 5 28 20 12 4

    该比特串分为长度相等的比特串C0和D0。然后C0和D0分别循环左移1位,得到C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2变换后即生成48比特的K1。K1的下标列表为:

    PC-2 14 17 11 24 1 5
    3 28 15 6 21 10
    23 19 12 4 26 8
    16 7 27 20 13 2
    41 52 31 37 47 55
    30 40 51 45 33 48
    44 49 39 56 34 53
    46 42 50 36 29 32

    C1、D1分别循环左移LS2位,再合并,经过PC-2,生成子密钥K2……依次类推直至生成子密钥K16。
    注意:Lsi (I =1,2,….16)的数值是不同的。具体见下表:

    迭代顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1


    生成子密钥的VC程序源代码
    如下:

    for(i=1;i<57;i++)//输入64位K,经过PC-1变为56位	  k0[i]=k[PC_1[i-1]];

    56位的K0,均分为28位的C0,D0。C0,D0生成K1和C1,D1。以下几次迭代方法相同,仅以生成K8为例。
    for(i=1;i<27;i++)//循环左移两位
    	{
    	  C8[i]=C7[i+2];
    	  D8[i]=D7[i+2];
    	}
    	C8[27]=C7[1];
    	D8[27]=D7[1];
    	C8[28]=C7[2];
    	D8[28]=D7[2];
    	for(i=1;i<=28;i++)
    	{
    	  C[i]=C8[i];
    	  C[i+28]=D8[i];
    	}
    	for(i=1;i<=48;i++)
    	  K8[i]=C[PC_2[i-1]];//生成子密钥k8
    

    注意:生成的子密钥不同,所需循环左移的位数也不同。源程序中以生成子密钥 K8为例,所以循环左移了两位。但在编程中,生成不同的子密钥应以Lsi表为准。



    三.解密

    DES的解密过程和DES的加密过程完全类似,只不过将16圈的子密钥序列K1,K2……K16的顺序倒过来。即第一圈用第16个子密钥K16,第二圈用K15,其余类推。
     
    L=R15, R=L15⊕f(R15,K16)⊕f(R15,K16)=L15
    同理R15=L14⊕f(R14,K15), L15=R14。
    同理类推:
    得 L=R0, R=L0。
    其程序源代码与加密相同。在此就不重写。

    四.示例
    例如:已知明文m=learning, 密钥 k=computer。
    明文m的ASCII二进制表示:

    m= 01101100 01100101 01100001 01110010
    01101110 01101001 01101110 01100111

    密钥k的ASCII二进制表示:

    k=01100011 01101111 01101101 01110000
    01110101 01110100 01100101 01110010

    明文m经过IP置换后,得:

    11111111 00001000 11010011 10100110 00000000 11111111 01110001 11011000

    等分为左右两段:

    L0=11111111 00001000 11010011 10100110 R0=00000000 11111111 01110001 11011000

    经过16次迭代后,所得结果为:

    L1=00000000 11111111 01110001 11011000 R1=00110101 00110001 00111011 10100101
    L2=00110101 00110001 00111011 10100101 R2=00010111 11100010 10111010 10000111
    L3=00010111 11100010 10111010 10000111 R3=00111110 10110001 00001011 10000100
    L4=00111110101100010000101110000100 R4=11110111110101111111101000111110
    L5=11110111110101111111101000111110 R5=10010110011001110100111111100101
    L6=10010110011001110100111111100101 R6=11001011001010000101110110100111
    L7=11001011001010000101110110100111 R7=01100011110011101000111011011001
    L8=01100011110011101000111011011001 R8=01001011110100001111001000000100
    L9=01001011110100001111001000000100 R9=00011101001101111010111011100001
    L10=00011101001101111010111011100001 R10=11101110111110111111010100000101
    L11=11101110111110111111010100000101 R11=01101101111011011110010111111000
    L12=01101101111011011110010111111000 R12=11111101110011100111000110110111
    L13=11111101110011100111000110110111 R13=11100111111001011010101000000100
    L14=11100111111001011010101000000100 R14=00011110010010011011100001100001
    L15=00011110010010011011100001100001 R15=01010000111001001101110110100011
    L16=01010000111001001101110110100011 R16=01111101101010000100110001100001

    其中,f函数的结果为:

    f1=11001010001110011110100000000011 f2=00010111000111011100101101011111
    f3=00001011100000000011000000100001 f4=11100000001101010100000010111001
    f5=10101000110101100100010001100001 f6=00111100111111111010011110011001
    f7=11110101101010011100000100111100 f8=10000000111110001010111110100011
    f9=01111110111110010010000000111000 f10=10100101001010110000011100000001
    f11=01110000110110100100101100011001 f12=00010011001101011000010010110010
    f13=10001010000010000100111111111100 f14=11100011100001111100100111010110
    f15=10110111000000010111011110100111 f16=01100011111000011111010000000000

    16个子密钥为:

    K1=11110000101111101110111011010000 K2=11100000101111101111011010010101
    K3=11110100111111100111011000101000 K4=11100110111101110111001000011010
    K5=11101110110101110111011100100110 K6=11101111110100110101101110001011
    K7=00101111110100111111101111100110 K8=10111111010110011101101101010000
    K9=00011111010110111101101101000100 K10=00111111011110011101110100001001
    K11=00011111011011011100110101101000 K12=01011011011011011011110100001010
    K13=11011101101011011010110110001111 K14=11010011101011101010111110000000
    K15=11111001101111101010011011010011 K16=11110001101111100010111000000001

    S盒中,16次运算时,每次的8 个结果为:
    第一次:5,11,4,1,0,3,13,9;
    第二次:7,13,15,8,12,12,13,1;
    第三次:8,0,0,4,8,1,9,12;
    第四次:0,7,4,1,7,6,12,4;
    第五次:8,1,0,11,5,0,14,14;
    第六次:14,12,13,2,7,15,14,10;
    第七次:12,15,15,1,9,14,0,4;
    第八次:15,8,8,3,2,3,14,5;
    第九次:8,14,5,2,1,15,5,12;
    第十次:2,8,13,1,9,2,10,2;
    第十一次:10,15,8,2,1,12,12,3;
    第十二次:5,4,4,0,14,10,7,4;
    第十三次:2,13,10,9,2,4,3,13;
    第十四次:13,7,14,9,15,0,1,3;
    第十五次:3,1,15,5,11,9,11,4;
    第十六次:12,3,4,6,9,3,3,0;

    子密钥生成过程中,生成的数值为:

    C0=0000000011111111111111111011 D0=1000001101110110000001101000
    C1=0000000111111111111111110110 D1=0000011011101100000011010001
    C2=0000001111111111111111101100 D2=0000110111011000000110100010
    C3=0000111111111111111110110000 D3=0011011101100000011010001000
    C4=0011111111111111111011000000 D4=1101110110000001101000100000
    C5=1111111111111111101100000000 D5=0111011000000110100010000011
    C6=1111111111111110110000000011 D6=1101100000011010001000001101
    C7=1111111111111011000000001111 D7=0110000001101000100000110111
    C8=1111111111101100000000111111 D8=1000000110100010000011011101
    C9=1111111111011000000001111111 D9=0000001101000100000110111011
    C10=1111111101100000000111111111 D10=0000110100010000011011101100
    C11=1111110110000000011111111111 D11=0011010001000001101110110000
    C12=1111011000000001111111111111 D12=1101000100000110111011000000
    C13=1101100000000111111111111111 D13=0100010000011011101100000011
    C14=0110000000011111111111111111 D14=0001000001101110110000001101
    C15=1000000001111111111111111101 D15=0100000110111011000000110100
    C16=0000000011111111111111111011 D16=1000001101110110000001101000

    解密过程与加密过程相反,所得的数据的顺序恰好相反。在此就不赘述。

    参考书目:

    《计算机系统安全》 重庆出版社 卢开澄等编著
    《计算机密码应用基础》 科学出版社 朱文余等编著
    《Visual C++ 6.0 编程实例与技巧》 机械工业出版社 王华等编著

     
    展开全文
  • 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为密文,使其只能在输入相应的密钥之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人窃取、...
  • 现代密码算法---DES算法

    千次阅读 2018-04-16 14:30:37
    上一期,我介绍了密码学的基本理论,然后还介绍了最古老的代换密码凯撒密码。当然了古典密码还有很多比如仿射密码、Hill密码、Play fair密码等等,我在这里就不一一介绍了,毕竟这些古典密码基本已经没什么实用价值...
  • 密码学02(DES算法

    2019-12-02 11:11:47
    DES算法分组密码Feistel结构Des算法初始IP置换子密钥生成F函数逆初始置换弱密钥、三重DES 分组密码 分组密码将明文M划分为一系列明文块Mi,每一块Mi包含若干位或字符,每一块用同一个密钥K加密。 Feistel结构 ...
  • DES加密算法的C语言实现,运行环境VC++6.0,使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥...
  • DES加密算法编程实现

    万次阅读 2017-03-31 21:46:15
    软件学院 陈春华 (博士) 实验目的 通过使用DES 算法对实验数据进行加密和解密,掌握现代分组密码算法基本原理,熟练掌握DES 算法各部件运算原理和具体运算过程。实验原理 现在密码算法可分为对称密码(Symmetric...
  • DES加密算法

    2016-05-16 11:38:36
    DES 使用一个 56 位密钥以及附加 8 位奇偶校验位,产生最大 64 位分组大小。这是一个迭代分组密码,使用称为 Feistel 技术,其中将加密文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与...
  • 通过使用DES 算法对实验数据进行加密和解密,掌握现代分组密码算法基本原理,熟练掌握DES 算法各部件运算原理和具体运算过程。 二、 实验原理 现在密码算法可分为对称密码(Symmetric Cryptology)和非对称密码...
  • S-DES算法java实现(源码下载)

    千次阅读 2010-11-25 00:36:00
    <br />今天上午分析了一下S-DES算法的大概流程,因为小区要停电,所以只是简单的分析了一下。实现是今天晚上写出来的。 有了DES分析的过程之后,S-DES的分析和实现都简单多了。以至于实现的时候直接看这...
  • 对于传统的经典加密算法如替换加密算法、DES算法、AES算法等基本都是对称的,也就是加密与解密过程有对称性,因此这些算法都容易被暴力破解。但是对于RSA算法的加密过程,它不具有对称性
  • 写在前面:   1、本文中DES加解密基本流程及S盒等参数参照...1. DES算法理论介绍   具体可参见杨波《现代密码学(第四版)》。本文只做简要介绍。 1.1 DES介绍   DES全称为Data Encryption Standard,即数据加密标
  • DES的基本结构为Feistel网络。(一)Feistel网络的加密过程在Feistel网络中,加密的各个步骤,称为轮round,整个加密过程就是经过若干次轮的循环。下图是Feistel网络一轮的运行过程。用文字描述一轮:1. 将输入的...
  • 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为【密文】,使其只能在输入相应的【密钥】之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人...
  • 经过不断尝试,一直是错,但是函数一个个都试功能正常,于是我开始怀疑是步骤问题,果不其然!!!终于成功了!! 错在哪呢?大家知道明文被分成LEFT 和RIGHT吧。。...当开始使用这两个部分...看下面的过程: ...
  • DES加密解密算法Java实现

    千次阅读 2017-03-16 13:58:58
    DES 使用一个 56 位密钥以及附加 8 位奇偶校验位,产生最大 64 位分组大小。这是一个迭代分组密码,使用称为 Feistel 技术,其中将加密文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与...
  • DES的原理及python实现

    2020-12-22 07:29:26
    DES是一种对称加密算法【即发送者与接收者持有相同的密钥】,它的基本原理是将要加密的数据划分为n个64位的块,然后使用一个56位的密钥逐个加密每一个64位的块,得到n个64位的密文块,最后将密文块拼接起来得到最终...
  • DES的几个问题

    2020-05-17 16:04:23
    DES算法对明文处理的基本过程 明文分组长为64比特,密钥长为56比特。明文处理过程分为3个阶段:首先是一个初始置换IPIPIP,用于重排明文分组的64比特数据。然后是具有相同功能的16轮变换,每轮中都有置换和代换运算...
  • Java 3DES加密解密(Commons.Codec Base64)

    万次阅读 2017-08-09 11:09:10
    它以DES为基本模块,通过组合分组方法设计出分组加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密表。 3DES加密过程为:C=Ek3(Dk2(Ek1(P))) 。3DES...
  • 非对称加密算法,诸如RSA或DES算法,被用于密钥变换。类似的过程,例如,被用于相当有效的保密PGP( Pretty cooct Privacy)。它使用了DES和RSA算法,这种混合处理的基本好处是对于大量数据的真正加密可以用对称加密...
  • 加密算法基本上可以分为三类,分别是对称性加密算法、非对称性加密算法和消息摘要算法,每一类算法中又有多个不同具体算法,下面就分别进行介绍。 对称性加密算法 对称性加密算法使用同一个密钥对信息进行加密和...
  • 第二十一讲 DES的轮函数及密钥编排

    千次阅读 2020-07-30 23:18:58
    DES算法轮结构 函数f(R,K)计算过程 选择扩展运算E 选择压缩运算S DESS盒 DESS-盒输入和输出关系 P盒置换 将S-盒变换后32比特数据再进行P盒置换,置换后得到32比特即为 f 函数 输出...
  • DES & 3DES

    千次阅读 2018-10-08 15:53:47
    DES(Data Encryption Standard)数据加密标准算法,采用56bits密钥加密64bits数据成密文一种分组密码,其基本结构为Feistel,共计16Round(轮)。 分组密码设计两个原则:混淆(Confusion)和扩散(Diffusion) ...

空空如也

空空如也

1 2 3 4 5 6
收藏数 105
精华内容 42
关键字:

des算法的基本过程