RSA和DES算法实现实验

一、实验角色

我是第十一小组的一位组员。我的任务是实现RSADES算法,并且提供加密和解密的接口,也就是说,能够对明文进行加密,对密文进行解密。我的主要工作是写一个类库,用户可以通过该类库提供的接口调用该类库中的函数,从而实现对数据的加密操作和解密操作。

二、实验要求

实现RSA算法的加密和解密。

实现DES算法的加密和解密。

 

三、实验原理

RSA算法(公开密钥算法)的原理:

RSA算法基于数论中的一些问题。我在这里只是简要的说明如何使用该方法,有关详细的信息请参考相关的资料。

1.  选择两个大的素数pq(典型情况下为1024位)

2.  计算n = p * q z =p-1*q-1.

3.  选择一个与z互素的数,将它称为d

4.  找到e,使其满足e*d  = 1 mod  z

提前计算出这些参数以后,我们就可以开始执行加密了。首先将明文分成块,使得每个明文消息P落在间隔0*P<n中。为了做到这一点,只要将明文划分成k位的块即可,这里k是满足2^k<n的最大整数。

为了加密一个消息P,只要计算C=P^e(mod n) 即可。为了解密C,只要计算P=C^d(mod n)即可。可以证明,对于指定范围内的所有P,加密盒解密互为反函数。为了执行加密,你需要en;为了执行解密,你需要dn。因此,公钥是有(en)对组成,而私钥是有(dn)对组成。

RSA算法的安全性建立在分解大数的困难基础之上。RSA加密解密算法的要点如下:

1.  密钥是成对产生的。

2.  加密密钥不能用来解密。

3.  加密密钥和算法是公开的,解密密钥是保密的。

4.  从加密密钥推出解密密钥十分困难。

   

RSA算法的模型:

加密和解密算法举例:

     选择p = 3 q = 11,则,n = p * q = 33 z = p – 1*q – 1= 20,因为7

20 互质,所以选择d = 7,选择e = 3 ,使得d * e = 1(mod 20),即计算密文C = P^3(mod 33),加密密钥为(333);计算明文P = C^7 (mod 33),解密密钥为(733)。

P = 2^k < 33k = 5 ,即用5 bit 表示一个信息,有32 种表示。

分别用其中1——26表示A——Z 26个字母,如明文为SUZANNE,密文就为

19 21 26 01 14 14 05

 

 

 

DES算法(对称密钥算法)的原理:

     在介绍DES数据加密算法之前,先介绍一下DES算法中需要用到的两种硬件设备:

P盒与S盒。P盒效果相当于对一个8位输入实现一个转置操作。S盒的效果相当于对一个3位的输入实现一个置换操作。

     当我们将一系列这样的S盒与P盒叠加起来构成乘积密码是,这些基本元素的威力就会发挥出来。

 

 

DESData Encryption Standard)数据加密算法,在工业界广泛应用于安全产品中。

DES的基本结构如下左图所示:

     明文按64位数据块的单元被加密,生成64位密文。DES算法带有一个56位密钥作为参数,它共有19个步骤。第一步是一个与密钥无关的转置操作,它直接作用在64位明文上。最后一步正好是这个转置操作的逆操作。最后一步之前的那个步骤是交换左32位和右32位。剩下的16步在功能上是完全相同的,但使用了原始密钥的不同函数作为参数。DES算法的设计允许使用同样的密钥来完成加密和解密过程。在DES算法中,解密的步骤只是解密步骤地相反顺序而已。这些中间步骤的操作情况如下右图所示。每个步骤接受232位输入,并产生两个32位输出。左边的输出只是右边输入的一份副本而已。右边的输出是左边输入与一个函数值逐位异或的结果,该函数的输入参数是右边的输入和当前步骤地密钥Ki。所有的复杂性都在这个函数种。

     此函数包含4个顺序执行的步骤。第一步,根据一个固定的转置和复制规则,将32Ri-1扩展成一个48位的数字E。第二步,EKi被异或在一起。然后,异或的结果被分成86位组,每个6位组被输入到不同的S盒中。对于每个S盒,共有64种可能的输入,每种输入被映射到一个4位输出上。最后,将这8*4位通过一个P盒。

 

 

 

 

 

四、实验步骤与程序:

 

鉴于我写的是一个类库,对用户提供调用的接口,而把实现封装起来,用户只要根据他的需要调用相应的函数,而不用关心具体的实现细节。至于实验的步骤,由于只是一个类库,用户只要调用他感兴趣的函数就可以了,具体的步骤由用户自己决定,我只是提供一些方法而已。

 

RSA类库的源代码:

 

using System;

using System.IO;

using System.Text;

using System.Security.Cryptography;

 

 

class RSAExchange

        {

               

                private RSAParameters publicKey;      //公钥

                private RSAParameters privateKey;     //私钥

                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

                public void setPublicKey()            //设置公钥

                {

                        publicKey = RSA.ExportParameters(false);

                       

                }

 

                public void setPrivateKey()       //设置私钥

                {

                        privateKey = RSA.ExportParameters(true);

                }

                public RSAParameters getPublicKey()    //返回RSAParameters类型的公钥

                {

                        return publicKey;

                }

 

                public RSAParameters getPrivateKey()   //返回RSAParameters类型的私钥

                {

                        return privateKey;

                }

               

 

                public string getPublicKeyXml()                 //返回string类型的公钥

                {

                        return RSA.ToXmlString(false);

                }

 

                public string getPrivateKeyXml()                //返回string类型的私钥

                {

                        return RSA.ToXmlString(true);

                }

       

 

                 public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)

                {               // byte 型的数据用公钥进行加密,公钥类型RSAParameters

// byte [] DataToEncrypt 明文

                                // RSAParameters RSAKeyInfo 公钥

                        try

                        {   

                                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

                                RSA.ImportParameters(RSAKeyInfo);

                                return RSA.Encrypt(DataToEncrypt, DoOAEPPadding);

                        }

                               

                        catch(CryptographicException e)

                        {

                                Console.WriteLine(e.Message);

 

                                return null;

                        }

 

                }

 

 

 

                 public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo,bool DoOAEPPadding)

                {                       // byte 型的数据用私钥进行解密        ,私钥类型 RSAParameters               

//byte [] DataToDecrypt 密文

                                        //RSAParameters RSAKeyInfo 私钥

                        try

                        {

                                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

                                RSA.ImportParameters(RSAKeyInfo);

                                return RSA.Decrypt(DataToDecrypt, DoOAEPPadding);

                        }

                               

                        catch(CryptographicException e)

                        {

                                Console.WriteLine(e.ToString());

                                return null;

                        }

 

                }

 

   

                public byte[] EncryptDataWithPublicKey(byte[] dataToEncrypt,string publicKey)

                {               // byte 型的数据用公钥进行加密,公钥类型 string

                                // byte [] DataToEncrypt 明文

                                //string publicKey 公钥

                        RSAExchange re = new RSAExchange();

                        re.RSA.FromXmlString(publicKey);

                        re.setPublicKey();

                        byte[] encryptedData;

                        encryptedData = re.RSAEncrypt(dataToEncrypt,re.getPublicKey(),false);

                        return encryptedData;

                }

 

                public byte[] DecryptDataWithPrivateKey(byte[] dataToDecrypt,string privateKey)

                {                       // byte 型的数据用私钥进行解密        ,私钥类型 string              

//byte [] DataToDecrypt 密文

                                        //string privateKey 私钥

 

                        RSAExchange re = new RSAExchange();

                        re.RSA.FromXmlString(privateKey);

                        re.setPrivateKey();

                        byte[] decrypteData;

                        decrypteData = re.RSADecrypt(dataToDecrypt,re.getPrivateKey(),false);

                        return decrypteData;

         }

 

 

DES类库的源代码:

class DESExchange

        {

 

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();

                byte[] DESKey;

                byte[] DESIV;

 

                public ICryptoTransform getEncryptor()

                {

                        return des.CreateEncryptor();

                }

 

                public ICryptoTransform getDecryptor()

                {

                        return des.CreateDecryptor();

                }

 

                public void setKey()            //设置DES密钥

                {

                        des.GenerateKey();

                        DESKey = des.Key;

                }

                public void setIV()             //设置位移矢量

                {

                        des.GenerateIV();

                        DESIV = des.IV;

                }

 

                public byte[] getDESKey()       //返回 byte [] 型的 DES密钥

                {

                        return DESKey;

                }

 

                public byte[] getDESIV()        //返回 byte [] 型的 位移矢量

                {

                        return DESIV;

                }

                public string getDESKeyStr()    //返回 string 类型的 DES密钥

                {

                        UnicodeEncoding ByteConverter = new UnicodeEncoding();

                        return ByteConverter.GetString(DESKey);

                }

 

                public string getDESIVStr()             //返回 string 类型的 位移矢量

                {

                        UnicodeEncoding ByteConverter = new UnicodeEncoding();

                        return ByteConverter.GetString(DESIV);

                }

 

                public byte[] EncryptData(byte[] dataToEncrypt,byte[] desKey,byte[] desIV)

                {               //DES密钥和位移矢量对数据进行加密

                                //被加密的数据类型 byte []

                                //DES密钥类型           byte []

                                //位移矢量类型  byte []

                        ICryptoTransform transformer = des.CreateEncryptor(desKey,desIV);

                        byte[] result ;

                        result = transformer.TransformFinalBlock(dataToEncrypt,0,dataToEncrypt.Length);

                        return result;

                }

               

                public byte[] EncryDataWithKeyIv(byte [] dataToEncrypt,string deskey,string desiv)

                {               //DES密钥和位移矢量对数据进行加密

                                //被加密的数据类型 byte []

                                //DES密钥类型           string

                                //位移矢量类型  string

 

                        UnicodeEncoding ByteConverter = new UnicodeEncoding();

                        byte [] DESkey = ByteConverter.GetBytes(deskey);

                        byte [] DESiv = ByteConverter.GetBytes(desiv);

                        byte [] result;

                        result = EncryptData(dataToEncrypt,DESkey,DESiv);

                        return result;

 

                }

 

                public byte[] DecryptData(byte[] dataToDecrypt,byte[] desKey,byte[] desIV)

                {               //DES密钥和位移矢量对数据进行解密

                                //被解密的数据类型 byte []

                                //DES密钥类型           byte []

                                //位移矢量类型  byte []

 

                        ICryptoTransform transformer = des.CreateDecryptor(desKey,desIV);

                        byte[] result ;

                        result = transformer.TransformFinalBlock(dataToDecrypt,0,dataToDecrypt.Length);

                        return result ;

                }

 

                public byte[] DecryptDataWithKeyIv(byte[] dataToDecrypt,string deskey,string desiv)

                {               //DES密钥和位移矢量对数据进行解密

                                //被解密的数据类型 byte []

                                //DES密钥类型           string

                                //位移矢量类型  string

 

                        UnicodeEncoding ByteConverter = new UnicodeEncoding();

                        byte [] DESkey = ByteConverter.GetBytes(deskey);

                        byte [] DESiv = ByteConverter.GetBytes(desiv);

                        byte [] result;

                        result = DecryptData(dataToDecrypt,DESkey,DESiv);

                        return result;

                }

 

                public static void EncryptData(String inName, String outName, byte[] desKey, byte[] desIV)

{        //  inName 文件中的数据用DES密钥和位移矢量进行加密,把加密后的密文存放在 //文件 outName

                        FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);

                        FileStream fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);

                        fout.SetLength(0);

      

                       

                        byte[] bin = new byte[100];

                        long rdlen = 0;             

                        long totlen = fin.Length;   

                        int len;                    

 

                        DES des = new DESCryptoServiceProvider();         

                        CryptoStream encStream = new CryptoStream(fout, des.CreateEncryptor(desKey, desIV), CryptoStreamMode.Write);

               

                        Console.WriteLine("Encrypting...");

 

                       

                        while(rdlen < totlen)

                        {

                                len = fin.Read(bin, 0, 100);

                                encStream.Write(bin, 0, len);

                                rdlen = rdlen + len;

                                Console.WriteLine("{0} bytes processed", rdlen);

                        }

 

                        encStream.Close(); 

                        fout.Close();

                        fin.Close();                  

                }

 

 

 

                public static void DecryptData(String inName, String outName, byte[] desKey, byte[] desIV)

{               //  inName 文件中的数据用DES密钥和位移矢量进行解密,把加密后的密文存放在

//文件 outName

                       

                        FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);

                        FileStream fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);

                        fout.SetLength(0);

      

                       

                        byte[] bin = new byte[100];

                        long rdlen = 0;             

                        long totlen = fin.Length;   

                        int len;                   

 

                        DES des = new DESCryptoServiceProvider();         

                        CryptoStream encStream = new CryptoStream(fout, des.CreateDecryptor(desKey, desIV), CryptoStreamMode.Write);

               

                        Console.WriteLine("Encrypting...");

 

                       

                        while(rdlen < totlen)

                        {

                                len = fin.Read(bin, 0, 100);

                                encStream.Write(bin, 0, len);

                                rdlen = rdlen + len;

                                Console.WriteLine("{0} bytes processed", rdlen);

                        }

 

                        encStream.Close(); 

                        fout.Close();

                        fin.Close();                  

         }

 

 

五、思考题

1.  RSA算法适不适合对大量的数据进行加密?DES算法呢?

2.  RSADES的加密速度哪一个跟快一点?

3.  RSADES的可靠性如何?

 

六、个人日志

5020339157 朱刚的个人日志文件

七、文档

 

见组文档

八、参考文献

1            William Stallings

《密码编码学与网络安全:原理与实践》 第二版

电子工业出版社 20014

2            Andrew S.Tanenbaum

《计算机网络 第四版

     清华大学出版社 2004 8

3Charles Wright

C#编程技术与技巧》

     机械工业出版社 2002 9

4Peter Thorsteinson  & G.Gnana Arun Ganesh

.NET安全性与密码术》

     清华大学出版社 2004 8

 

九、开发小结:

这次的网络大作业是我参与的第一个大型的软件开发项目,也是第一次和其他同学合作一起开发一个软件。虽然是初次合作,也没有什么软件开发的经验,但我感觉到我们的开发团队非常的团结,每个人都很有团队合作的精神,互相帮助,有什么问题都能够一起讨论,不管是一开始的软件设计阶段,还是后来的编码和调试阶段,大家的心都很齐,碰到了什么技术问题,或是其他的在编程过程中出现的问题,大伙都群策群力,集思广益,热烈的讨论最佳的解决方法,在整个的开发开发过程中,克服了一个又一个技术难关,最终完成了整个系统的设计,开发,调试。虽然最后做出来的软件还略显粗糙,不够完善,但那也是我们开发团队每个成员辛勤努力的结果,我感到很欣慰。通过这次的网络大作业,我觉得自己有两方面的收获:首先是学会了怎么去和团队中的其他成员如何相处,如何合作,如何一起解决一个问题,明白了团队精神的重要性,也知道自己以后怎么去很好的融入一个团队。其次,在技术方面,我的工作是实现RSADES的加密和解密,通过实际的编程,对这方面的东西有了比较深的了解,可以说初步掌握了对数据的加密和解密。

posted on 2008-11-27 09:56  青春的虎子  阅读(2528)  评论(0)    收藏  举报

导航