密码学课程设计实验报告

时间:2024.4.21

未命名1

hust1

密码学课程设计实验报告

      计算机科学与技术学院  

            信息安全         

               0703          

            xxxxxxxxxx      

             xxxxxx         

指导教师         xxxxxxxx       

     20##     3    18  

目录

第一部分

一、实验目的... 4

二、实验环境及工具... 4

三、实验内容... 4

四、实验原理... 4

五、实验过程... 6

5.1设计思路... 6

5.2程序的实现部分... 11

六、程序测试... 12

6.1制定测试方案... 12

6.2测试效果... 12

七、源代码... 13

第二部分

一、实验目的... 14

二、实验环境及工具... 14

三、实验内容... 14

四、实验原理... 14

五、实验过程... 14

5.1设计思路... 14

5.2程序的流程图... 17

六、程序测试... 19

6.1制定测试方案... 19

6.2测试效果... 20

七、源代码... 20

第三部分

实验总结... 21

第一部分三圈DES的差分攻击

一、实验目的

通过课程设计,使学生进一步熟悉密码算法以及算法安全性的基本概念和原理;培养学生将密码理论和技术应用于实际的能力,使学生具备实施数据加/脱密和基本的密码分析的能力。

二、实验环境及工具

         操作系统         Microsoft windows XP Home Edition 版本2002 Service Pack3

         IDE环境           Microsoft Visual C++ 6.0 (SP6)

         硬件环境         Intel(R)Atom? CPU N270 @1.60GHz,0.99GB的内存物理地址扩展

三、实验内容

题目:三圈DES的差分攻击;

要求:设计必需的界面环境,

(1)         输入明文及其对应的密文,产生相应的密钥

(2)        设计有好的窗口显示实验结果

四、实验原理

DES加密算法中的各种置换和扩展对差分没有影响,只有S盒可以阻挡差分;设 △X=X1⊕X2,△Y=Y1⊕Y2,其中X1和X2是S盒的六位输入,Y1和Y2是相应的四位输出即X1->S=Y1,X2->S=Y2;那么我们就可以以△X为行索引,以△Y为列索引建立一个64*16的二维矩阵,矩阵中的元素为可能的X值,我们把这个矩阵称作S盒的差分表,如下表所示:

我们一共可以构造八个差分表,下面我们给出三圈DES的加密过程(省略了IP置换):

在选择明文攻击的情况下我们很容易保证△R0=0,那么我们就可以得到下列式子:

1)  

          △A=E(△L3);

2)             △B=P(△R3⊕△L0)

由于△L3、△R3、△L0在选择明文攻击时都是可求的,所以△A、△B也是可求的。

由于A是S盒的输入B是S盒的输出,我们又能求得△A、△B所以我们通过查差分表就可以把A局限在一个较小的范围内(在这个范围内穷举是可行的),又由于K3=A⊕C= A⊕E(L3),所以子密钥K3也被局限到了一个较小的范围内而DES的主密钥K的穷举时间是K3的256倍,所以穷举K也是可行的。

五、实验过程

       5.1设计思路

       其实具体的算法已经在实验原理中给出了,我就是按照此原理设计了一个CAttack类用来进行差分攻击,下面是它的头文件:

// Attack.h: interface for the CAttack class.

//

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ATTACK_H__5C3E3C22_41EC_4D03_8249_6A9D80ECFA07__INCLUDED_)

#define AFX_ATTACK_H__5C3E3C22_41EC_4D03_8249_6A9D80ECFA07__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include "DES.h"

#define PLAINTEXT0  0

#define PLAINTEXT1  1

#define ENCRYPTOGRAPH0  2

#define ENCRYPTOGRAPH1  3

#define PLAINTEXT2  4

#define PLAINTEXT3  5

#define ENCRYPTOGRAPH2  6

#define ENCRYPTOGRAPH3  7

class CAttack : public CDES

{

public:

    CAttack();

    virtual ~CAttack();

    /**************************************************************************

    //  名称:InitAttack

    //  功能:初始化8个S盒的差分表

    //  参数:

    //  返回:

    //  备注:

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    void InitAttack();

    /**************************************************************************

    //  名称:TryAttack

    //  功能:进行差分攻击

    //  参数:key:[out] 返回破解出来的密钥

    //  返回:成功为TURE,否则为FALSE

    //  备注:成功为TURE,否则为FALSE

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    BOOL TryAttack(CString &key);

   

    /**************************************************************************

    //  名称:SetData

    //  功能:设置破解参数

    //  参数:nFlag:[in] 参数标志

    //        str:  [in] 参数值

    //  返回:成功为TURE,否则为FALSE

    //  备注:

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    BOOL SetData(UINT nFlag,CString& str);

protected:

    /**************************************************************************

    //  名称:CalcDelta

    //  功能:计算各个差分值

    //  参数:byPlaintext0:[in] 明文串0

    //        byEncryptograph0: [in] 密文串0

    //        byPlaintext1:[in] 明文串1

    //        byEncryptograph1: [in] 密文串1

    //  返回:

    //  备注:

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    void CalcDelta(BYTE byPlaintext0[],BYTE byEncryptograph0[],BYTE byPlaintext1[],BYTE byEncryptograph1[]);

   

    /**************************************************************************

    //  名称:BitToUint

    //  功能:二进制位串到整型数据的转换

    //  参数:byt:[in] 二进制串

    //        len:  [in] 二进制串的长度

    //  返回:转换结果

    //  备注:

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    UINT BitToUint(BYTE byt[],UINT len);

   

    /**************************************************************************

    //  名称:UintToBit

    //  功能:整型数据到二进制位串的转换

    //  参数:byt:[out] 二进制串

    //        len:  [in] 二进制串的长度

    //        n:    [in] 整数

    //  返回:

    //  备注:

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    void UintToBit(BYTE byt[],UINT len,UINT n);

   

    /**************************************************************************

    //  名称:CalcSubkey

    //  功能:计算所有可能的子密钥K3

    //  参数:R:[in] 密文的右半部分

    //        delX: [in] x的差分

    //        delY: [in] y的差分

    //        subkey:[out]可能的子密钥

    //  返回:

    //  备注:

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    void CalcSubkey(BYTE R[],BYTE delX[],BYTE delY[],CList<BYTE,BYTE> subkey[]);

   

    /**************************************************************************

    //  名称:CalcSubkey

    //  功能:穷举56位主密钥

    //  参数:

    //  返回:成功为TURE,否则为FALSE

    //  备注:

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    BOOL CalcMainKey();

    /**************************************************************************

    //  名称:Conjoin

    //  功能:求子密钥交集的函数key2=key2交key1

    //  参数:key2[in/out]:子密钥key2集合

    //        key1[in]:子密钥key1集合

    //  返回:

    //  备注:

    //  更新:2010/3/10

    //  作者:王凤伟

    /**************************************************************************

    void Conjoin(CList<BYTE,BYTE> key2[],CList<BYTE,BYTE> key1[]);

protected:

    CList<BYTE,BYTE> m_s[8][64][16];// 用于保存差分表

    CList<BYTE,BYTE> m_Key1[8];     // 用于保存可能子密钥集合的链表

    CList<BYTE,BYTE> m_Key2[8];     // 用于保存可能子密钥集合的链表

    BYTE m_byAttackedSubKey[ROUND][48]; // 3圈子密钥

    BYTE m_byAttackedDesKey[56];            // 密钥

    CString m_strAttackedDesKey;    // 密钥串

    BYTE m_byEncryptograph0[64];    // 密文0

    BYTE m_byPlaintext0[64];        // 明文0   

    CString m_strPlaintext0;    // 明文串0

    CString m_strEncryptograph0;    // 密文串0

    BYTE m_byEncryptograph1[64];    // 密文1

    BYTE m_byPlaintext1[64];        // 明文 1

    CString m_strPlaintext1;    // 明文串1

    CString m_strEncryptograph1;    // 密文串1

    BYTE m_byEncryptograph2[64];    // 密文2

    BYTE m_byPlaintext2[64];        // 明文2   

    CString m_strPlaintext2;    // 明文串2

    CString m_strEncryptograph2;    // 密文串2

    BYTE m_byEncryptograph3[64];    // 密文3

    BYTE m_byPlaintext3[64];        // 明文3   

    CString m_strPlaintext3;    // 明文串3

    CString m_strEncryptograph3;    // 密文串3

    BYTE m_byDeltaL0[32];       // L0的差分

    BYTE m_byDeltaL3[32];       // L3的差分

    BYTE m_byDeltaR3_L0[32];    // R3的差分异或L0的差分

    BYTE m_byDeltaA[48];        // A的差分(S盒的输入)

    BYTE m_byDeltaB[32];        // B的差分(S盒的输出)

};

#endif // !defined(AFX_ATTACK_H__5C3E3C22_41EC_4D03_8249_6A9D80ECFA07__INCLUDED_)

5.2程序的实现部分

既然原理已经很清楚了,那么设计算法就不在困难了,这里我进一步给出算法的流程图,算法的详细内容请参照文件夹DES Attacker中的源程序。

   说明:保存subkey时并不是真正的保存subkey的完整部分,而是将subkey

每6位分为一组保存,这样可以大大地减少存储空间(乘法原理)。

六、程序测试

6.1制定测试方案

为了便于测试,我编写了一个简单的三圈DES加密程序(DES 3 Rounds.exe),可以在DES 3 Rounds文件夹中找到,由用户自主选择密钥和满足条件的明密文对,然后把相应的参数输入到三圈DES差分攻击主程序(DES Attacker.exe)中,进行破译,最后与用户的密钥进行比较。

6.2测试效果

6.2.1生成破解参数

运行程序DES 3 Rounds.exe,输入相应的明文和密钥,生成参数

图6.2.1生成破解参数

6.2.1进行破译

运行DES Attacker.exe,并把刚才生成的破解参数复制到相应的编辑框中。

图6.2.1 进行破译

七、源代码

由于该程序的主框架是由MFC的AppWizard生成的,代码量很大,所以就不把源代码放到实验报告里了,若要看源代码请打开当前目录下的DES Attacker文件夹。

一、实验目的

通过课程设计,使学生进一步熟悉密码算法以及算法安全性的基本概念和原理;培养学生将密码理论和技术应用于实际的能力,使学生具备实施数据加/脱密和基本的密码分析的能力。

二、实验环境及工具

         操作系统         Microsoft windows XP Home Edition 版本2002 Service Pack3

         IDE环境           Microsoft Visual C++ 6.0 (SP6)

         硬件环境         Intel(R)Atom? CPU N270 @1.60GHz,0.99GB的内存物理地址扩展

三、实验内容

题目:RSA解密密钥攻击;

要求:设计必需的界面环境,

(1)         加密密钥和解密密钥,求p、q,使n=p*q

(2)         设计有好的窗口显示实验结果

四、实验原理

    定理:已知k1,k2求p和q,k1*k2=m* (n)+1,若能求x*x=1(mod n)的非平凡根,则可求p和q且p=(x+1,n),q=(x-1,n);

         算法:(1)k1*K2-1->r;0->s;

                    (2)i+1->s,n=r/2;

                    (3)若2|r,则转(2),否则转(4);((2)-(3)步骤目的是求K1*K2=r*2^s)

                    (4)任取w,1<w<n-1;若(w,n)!=1,则p=(w,n);q=n/p,成功返回;否则转(5);

                    (5)w^r->V;若V=1,则转(4;否则转(6)

                    (6)r/2->r;V^r->tem;若tem=1则转(6);

                                                                 若tem=-1,则转(4)

否则p=(tem+1,n),q=(tem-1,n),成功

说明:算法的关键是第6步,在判断tem的值时,没有简单的判断tem=1tem=-1时直接重新计算随机数W,而是对tem=1的情况进行了优化,即在tem=1时,把V的指数除二然后得到新的tem,这种优化是必要的,也是有效的。因为

V^(2^s)是收敛于1的,也就是说在随着s的增大V^(2^s)=1的概率将越来越接近1,而若不把指数缩小很难找到tem!=1W值,这与利用穷举法分解N的效率相当。我曾经在没有优化的情况下做过实验,当时分解一个20位(16进制)的N,大约需要30分钟,而且都是在(w,n!=1的条件下返回的(这正是穷举的结果),而经过优化后分解的时间只有几百毫秒的时间,而且都是在第六步返回的。

五、实验过程

       5.1设计思路

       具体的算法已经在实验原理中给出了,我就是按照此原理设计了一个CAttack类用来进行大数分解,而其中最关键的就是CAttack::Attack()函数,下面给出了源代码:

#define CHECK(x)            {if( !(x) ) return false;}

bool CAttack::Attack()

{

    static BigInt r,tem,tem1,v,sem,m,rands,rands1;

    UINT i=0;

    // 利用简单的加解密判断用户输入的参数是否正确

    CHECK(m_OBigInt.PowMod(tem,m_OBigInt.Two,m_k1,m_n))

    CHECK(m_OBigInt.PowMod(tem1,tem,m_k2,m_n))

    CHECK(!m_OBigInt.Cmp(tem1,m_OBigInt.Two))

    CHECK(m_OBigInt.Mul(tem,m_k1,m_k2))

    CHECK(m_OBigInt.Sub(sem,tem,m_OBigInt.One))

    tem=sem;

   

    // 计算k1*k2-1=r*2^s

    do

    {

        r=tem;

        CHECK(m_OBigInt.Div(tem,rands,r,m_OBigInt.Two))

    } while (!m_OBigInt.Cmp(rands,m_OBigInt.Zero));

    // 2^s->m

    CHECK(m_OBigInt.Div(m,tem1,sem,r))

    // 生成随机数rands1

    CHECK(m_OBigInt.RandVal(rands1,m_n.len+1))

    do

    {

        do

        {

B:

            if (i>CYCLE)

            {

                i=0;

                CHECK(m_OBigInt.RandVal(rands1,m_n.len+1))

            }

            i++;

            // 生成满足条件1<rands<n-1的随机数rands

            rands=rands1;

            CHECK(m_OBigInt.Div(tem,rands,rands,m_n))

            CHECK(m_OBigInt.Add(rands1,rands,m_OBigInt.One))

        } while (!rands.len||!m_OBigInt.Cmp(rands,m_OBigInt.One)||!m_OBigInt.Cmp(rands1,m_n));

       

        // 计算(rands,n)

        CHECK(m_OBigInt.Glb(m_p,m_n,rands))

        // (m_n,rands)=1,破解成功

        if (m_OBigInt.Cmp(m_p,m_OBigInt.One))

        {

            CHECK(m_OBigInt.Div(m_q,tem,m_n,m_p))

            CGfL::HalfByteToStr(m_strP,m_p.bit,m_p.len);

            CGfL::HalfByteToStr(m_strQ,m_q.bit,m_q.len);

            return true;

        }

        // 计算rands^r->v

        CHECK(m_OBigInt.PowMod(v,rands,r,m_n))

        CHECK(m_OBigInt.Add(tem,v,m_OBigInt.One))

        // 若v=1或v=-1,则重新生成随机数

        if (!m_OBigInt.Cmp(v,m_OBigInt.One)||!m_OBigInt.Cmp(tem,m_n))

        {

            goto B;

        }

        tem1=m; // 2^s->tem

       

loop:   CHECK(m_OBigInt.Div(tem1,tem,tem1,m_OBigInt.Two))   // 计算tem1/2->tem1

        CHECK(m_OBigInt.PowMod(tem,v,tem1,m_n)) // 计算v^tem1->tem

       

        // 如果v^tem1=1,则计算v^(tem1/2)

        if(!m_OBigInt.Cmp(tem,m_OBigInt.One))

        {

            goto loop;

        }

        CHECK(m_OBigInt.Add(tem1,tem,m_OBigInt.One))

    }while(!m_OBigInt.Cmp(tem1,m_n)); // 如果v^tem1=-1则重新生成随机数rands,否则成功

    CHECK(m_OBigInt.Add(rands,tem,m_OBigInt.One))

    CHECK(m_OBigInt.Sub(rands1,tem,m_OBigInt.One))

    CHECK(m_OBigInt.Glb(m_p,rands,m_n))// p=(tem+1,n)

    CHECK(m_OBigInt.Glb(m_q,rands1,m_n))// q=(tem-1,n)

    CGfL::HalfByteToStr(m_strP,m_p.bit,m_p.len);

    CGfL::HalfByteToStr(m_strQ,m_q.bit,m_q.len);

    return true;

}

声明:大数的计算我用的是东北大学的开源的算法库CBigInt和通用库CGfL来实现的,在这里我向作者表示感谢。

5.2程序的流程图

六、程序测试

6.1制定测试方案

为了便于测试,我编写了一个简单的RSA参数生成程序(Generate RSA.exe),可以在Generate RSA文件夹中找到,由用户自主选择N的长度,然后把生成相应的参数输入到RSA已知密钥攻击主程序(RSA Attacker.exe)中,进行大数分解,最后与生成参数中的p、q比较。

6.2测试效果

6.2.1生成破解参数

运行程序Generate RSA.exe,输入N的长度,生成参数

图6.2.1生成破解参数

6.2.1进行破译

运行RSA Attacker.exe,并把刚才生成的破解参数复制到相应的编辑框中。

图6.2.1 进行破译

七、源代码

由于该程序的主框架是由MFC的AppWizard生成的,代码量很大,所以就不把源代码放到实验报告里了,若要看源代码请打开当前目录下的RSA Attacker文件夹。

第三部分

实验总结

通过本次课程设计,我对密码学原理有了更深入的理解,特别是通过编程实现三圈DES差分攻击和RSA解密密钥攻击,对DES和RSA密码算法的理解更加深刻,而且对差分攻击技术有了更清晰的认识,对概率算法也有了新的认识。

在编程的过程中也遇到了一些问题,如RSA解密密钥攻击中,开始时只是简单的随机选取W,然后判断V^(2^(s-1))是否为+1或-1,若不成功则重新选择W,最终导致所有的V^(2^(s-1))几乎都为1,使该算法蜕化为一般的穷举算法。经过不断地跟踪和分析,发现指数必须足够小,概率算法才能发挥作用,因此对算法做了改进,果然,改进后的算法效率很高,令我兴奋不已。在三圈DES差分攻击中,由于计算差分△B=P(△R3⊕△L0)时,错误地认为△B=△R3⊕△L0,也给调试制造了很多麻烦。

总之,通过独立完成此次课设,在编程的过程中遇到了很多问题,通过反复地分析与调试,将它们一一解决,锻炼了自己的分析问题和解决问题的能力。同时,通过实际编写密码分析程序,也极大地激发了我对密码学的兴趣,希望在以后的学习中不断地积累和丰富密码学的相关理论与技术。

更多相关推荐:
密码学课程设计报告

沈阳工程学院课程设计设计题目院系信息学院班级信安本111学生姓名学号指导教师祝世东王素芬职称工程师副教授起止日期20xx年1月6日起至20xx年1月10日止沈阳工程学院课程设计任务书课程设计题目简单的保密通信系...

密码学课程设计报告

密码学课程设计报告班级:信安10-1班姓名:学号:指导老师:一、Hash算法的实现MD5算法1.1算法概述MD5算法是一种消息摘要算法,此算法以任意长度的信息作为输入进行计算,产生一个128-bit(16-by…

密码学-RSA加密解密算法的实现课程设计报告

密码学课程报告《RSA加密解密算法》专业:信息工程(信息安全)班级:1132102学号:****姓名:***时间:20××年1月10号一、课程设计的目的当前最著名、应用最广泛的公钥系统RSA是在1978年,由美…

密码学课程设计报告

XX大学密码学课程设计姓名学号学院指导老师完成日期20xx0106一实验任务及要求任务使用IDEA算法实现加解密过程要求1输入至少包括两个分组2核心功能是加解密过程可适当增加附加功能32人组二实现原理IDEA算...

密码学课程设计报告要求及模板

计算机与信息工程学院《密码学课程设计》报告(20××/20学年第二学期)题目:Diffie-Hellman密钥交换协议系别:计算机与信息工程学院专业:信息安全班级:学号:姓名:20年05月30日(一)题目Dif…

中国矿业大学密码学课程设计报告

密码学课程设计中国矿业大学密码学课程设计报告院系计算机学院专业信息安全班级姓名学号指导老师20xx年6月密码学课程设计摘要近些年来由于许多私密信息的泄漏信息安全成为全社会的需求所以也成为了整个社会的关注热点对于...

现代密码学课程设计实验报告 -

西安科技大学《现代密码学》课程设计报告题目:密码学计算器学院:计算机科学与技术学院班级:姓名:学号:日期:20XX.1.8一.课程设计题目密码学计算器的研究与实现二.分工对称密码程序实现Des算法组长:古典密码…

密码学课程设计报告 5

密码学课程设计班级姓名学号指导教师20xx6中国矿业大学计算机学院密码学课程设计目录密码学课程设计11实验一实现一个多表古典加密和解密程序111实验目的112实验要求113实验内容114古典加密方法115程序代...

应用密码学课程设计报告

沈阳工程学院课程设计报告摘要摘要随着国家信息化步骤的加快和高等教育规模的扩大社会对计算机专业人才的需求不仅体现在数量的增加上而且体现在质量要求的提高上培养具有研究和实践能力的高层次的计算机专业人才已成为许多重点...

密码学课程设计报告

20xx20xx密码学课程设计报告密码学课程设计报告120xx20xx密码学课程设计报告一古典密码算法311实验内容312实验目的313需求分析314程序流程图415算法实现5151Playfair体制5151...

密码学课程设计

课程设计说明书NO1课程设计说明书NO2课程设计说明书NO3课程设计说明书NO4课程设计说明书NO5课程设计说明书NO6课程设计说明书NO7课程设计说明书NO8课程设计说明书NO9课程设计说明书NO10课程设计...

密码学课程设计

密码学课程设计学号班级姓名指导教师年7月420xx日AES加解密算法一原理AES是美国高级加密标准算法将在未来几十年里代替DES在各个领域中得到广泛应用随着对称密码的发展DES数据加密标准算法由于密钥长度较小5...

密码学课程设计报告(28篇)