Chinaunix首页 | 论坛 | 博客
  • 博客访问: 153091
  • 博文数量: 116
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 20
  • 用 户 组: 普通用户
  • 注册时间: 2017-08-21 15:04
文章分类

全部博文(116)

文章存档

2014年(1)

2013年(13)

2012年(27)

2011年(49)

2010年(26)

分类: C/C++

2011-08-10 13:30:53

作者:




  DES(Data Encrypton Standard) 算法的实现网上已经有很多,本人在此讲述的是在DES算法加密过程中如何查看16迭代过程中生成的Ki,Li,Ri,Fi,Si等,这样可以当做一个DES加密对照器,这样可以方便的发现你在加密过程中出现的错误!



图一:程序运行界面

  本程序用了一个列表框来显示所有16次迭代的所有信息,并在选择一栏后,在下面的编辑框中显示详细信息,这样就可以不必在列表框中拖曳鼠标,这样方便拷贝!

程序介绍:
采取的编程语言是微软的VC6.0,大小为184K!实现了简易的DES加密查看功能!功能介绍:
1:编辑框1:输入明文,只允许8位的ASCII码,不允许输入中文;
2:编辑框2:输入密钥,只允许8位的ASCII码,不允许输入中文;
3.加密按钮:对明文加密,并在下面显示加密后的二进制和ASCII码;
4.对每次加密解密显示 Ki, Li, Ri, Fi, Si的值;
5.对列表框的点击将会详细显示如下信息:
Ki:加密过程中产生的子密钥,共16个,每个48位
Li:加密过程中产生的子密钥,共16个,每个32位
Ri:加密过程中产生的子密钥,共16个,每个32位
Fi:加密过程中产生的子密钥,共16个,每个32位
Si:加密过程中产生的S值,共8个,每个大小为0~15
下面就由本人详细介绍在实现加密过程中需要注意的一些问题:

  在程序一开始的时候,我们需要在OnInitDialog这个函数内做一些初始化操作,对列表框的操作如下,让其显示条形,并插入要显示的项目:

  1. ////////////////////////////////////////////////////////////////////////
  2. CenterWindow(GetDesktopWindow());
  3.     ::SendMessage(m_listdata.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,
  4.         LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES,
  5.         LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
  6.     m_listdata.InsertColumn(0,"NO.",LVCFMT_LEFT,30);
  7.     m_listdata.InsertColumn(1,"L0",LVCFMT_LEFT,40);
  8.     m_listdata.InsertColumn(2,"R0",LVCFMT_LEFT,40);
  9.     m_listdata.InsertColumn(3,"F函数值",LVCFMT_LEFT,60);
  10.     m_listdata.InsertColumn(4,"密钥Ki",LVCFMT_LEFT,50);
  11.     m_listdata.InsertColumn(5,"S盒",LVCFMT_LEFT,45);
  12. ////////////////////////////////////////////////////////////////////////
  加密的过程中,需要对明文和密文检测,是否含有无法加密的字符,如中文字符,或者是否满足8位这个条件(本人并未对数据做未满8位以0补的处理):
  1. //////////////////////////////////////////////////////////////////////////
  2.     // 对输入的数据进行验证
  3.     if(m_old.GetLength()!=8)
  4.     {
  5.         MessageBox("请输入8位明文", "友情提示");
  6.         return;
  7.     }
  8.     if(m_key.GetLength()!=8)
  9.     {
  10.         MessageBox("请输入8位密文", "友情提示");
  11.         return;
  12.     }
对明文处理,将对应的ASCII码转化为二进制,并对中文字符的判断:
  1. //////////////////////////////////////////////////////////////////////////
  2.     /// 此处对明文处理,将对应的ASCII码转化为二进制    
  3.     int flag=true;
  4.     for(int i=0; i<8; i++)
  5.     {
  6.         char ch=m_old.GetAt(i);
  7.         if(ch&0x80&&flag)
  8.         {
  9.             MessageBox("含有中文字符,加密错误不负责任!", "友情提示");
  10.             flag=false;
  11.             //return;
  12.         }
  13.         memset(tmp, 0, 8);
  14.         for(int j=0; j<8; j++)
  15.         {
  16.             tmp[j]=(ch%2+2)%2;
  17.             ch/=2;
  18.         }
  19.         for(j=7; j>=0; j--)
  20.         {
  21.             old[i*8+7-j]=tmp[j];
  22.         }    
  23.     }
为了实现加密解密迭代算法的共享,本人做了如下处理:
  1. /// 此处开始16迭代算法
  2.     isDecrypt=false;
  3.     for(i=1; i<=16; i++)
  4.     {
  5.         CDESDlg::Iterate(i);
  6.     }
在16次迭代算法中,大部分操作是重复的,所以采取了上述的做法!在这里,本人把迭代算法的代码全部写在这里:
  1. void CDESDlg::Iterate(int numOfIteration)
  2. {
  3.     //////////////////////////////////////////////////////////////////////////
  4.     /// 此处迭代生成子密钥ki
  5.     int j=2;                    // 移位次数
  6.     if(    numOfIteration==1||numOfIteration==2||
  7.         numOfIteration==9||numOfIteration==16)
  8.     {
  9.         j=1;
  10.     }
  11.     //////////////////////////////////////////////////////////////////////////
  12.     //如果为解密,迭代移位的次序变换相反方向
  13.     if(isDecrypt)
  14.     {
  15.         if(numOfIteration==16)
  16.         {
  17.             j=0;
  18.         }
  19.         else if(numOfIteration==15||numOfIteration==8||numOfIteration==1)
  20.         {
  21.             j=-1;
  22.         }
  23.         else
  24.         {
  25.             j=-2;
  26.         }
  27.     }
  28.     
  29.     // 省略此部分代码.......
  30.     // 生成子密钥Ki,存储到数组k1[48]中去
  31.     //////////////////////////////////////////////////////////////////////////
  32.     // 将Ri-1扩充成48位并与Ki相加并模2
  33.     memset(re, 0, 48);
  34.     for(i=0; i<48; i++)
  35.     {    
  36.         re[i]=(R0[E_Table[i]-1]+k1[i])%2;
  37.     }
  38.     //////////////////////////////////////////////////////////////////////////
  39.     //     分成8组, 每组6位,有一个二维数组s[8][6]存储
  40.     for(i=0; i<6; i++)
  41.     {
  42.         for(int j=0; j<8; j++)
  43.         {
  44.             s[j][i]=re[6*j+i];
  45.         }
  46.     }
  47.     
  48.     //////////////////////////////////////////////////////////////////////////
  49.     // 以下通过8个S盒得到8个S数并存到S[8]中S_Box[8][4][16]
  50.     memset(s0, 0, 8);
  51.     for(i=0; i<8; i++)
  52.     {
  53.         s0[i]=S_Box[i][s[i][5]+s[i][0]*2][s[i][1]*8+s[i][2]*4+s[i][3]*2+s[i][4]];
  54.     }
  55.     
  56.     memset(stmp, 0, 8);
  57.     memcpy(stmp, s0, sizeof(s0));
  58.     //////////////////////////////////////////////////////////////////////////
  59.     // 将8个数分别转换成2进制,再存入到frk[32]
  60.     int f[32];
  61.     memset(f, 0, 32);
  62.     for(i=0; i<8; i++)
  63.     {
  64.         int tmp[4];
  65.         memset(tmp, 0, 4);
  66.         for(int j=0; j<4; j++)
  67.         {
  68.             tmp[j]=s0[i]%2;
  69.             s0[i]/=2;
  70.         }
  71.         for(j=0; j<4; j++)
  72.         {
  73.             f[4*i+j]=tmp[3-j];
  74.         }
  75.     }
  76.     
  77.     // 经过P变换存入frk[32]
  78.     for(i=0; i<32; i++)
  79.     {
  80.         frk[i]=f[P_Table[i]-1];
  81.     }
  82.     
  83.     int Ltmp[32], Rtmp[32];
  84.     memset(Ltmp, 0, 32);
  85.     memset(Rtmp, 0, 32);
  86.     
  87.     for(i=0; i<32; i++)
  88.     {
  89.         Ltmp[i]=R0[i];
  90.         Rtmp[i]=(L0[i]+frk[i])%2;
  91.     }
  92.     
  93.     // 最后将数据存入L0,RO里面去
  94.     for(i=0; i<32; i++)
  95.     {
  96.         L0[i]=Ltmp[i];
  97.         R0[i]=Rtmp[i];
  98.     }
  99.     
  100.     CDESDlg::SaveToList();
  101.     //////////////////////////////////////////////////////////////////////////
  102.     // 16次迭代算法结束,真累呀^_^
  103. }
  将数据存储到列表框是由函数CDESDlg::SaveToList()来实现的,这其实并不难,只要每次你将数据插入到列表框中就可以啦,可以看到如下:
  1. void CDESDlg::SaveToList()
  2. {
  3.     //////////////////////////////////////////////////////////////////////////
  4.     // 测试数据,将L, R, K, F, S数据存入列表
  5.     CString str, strl, strr, strs, strf, strk;
  6.     str="", strl="", strr="",
  7.     strk="", strs="", strf="";
  8.     item=m_listdata.InsertItem(0xffff, "N", 1);
  9.     str.Format("%d", item+1);
  10.     m_listdata.SetItem(item, 0, 1, str, NULL, 0, 0, 0);
  11.     // 上面将第第一列的值插入,显示为迭代次数
  12.     for(int k=0; k<32; k++)    
  13.     {
  14.         str.Format("%d", L0[k]);
  15.         strl+=str;
  16.         str.Format("%d", R0[k]);
  17.         strr+=str;
  18.     }
  19.     for( k=0; k<32; k++)    
  20.     {
  21.         str.Format("%d", frk[k]);
  22.         strf+=str;
  23.     }
  24.     for( k=0; k<48; k++)
  25.     {
  26.         str.Format("%d", k1[k]);
  27.         strk+=str;
  28.     }
  29.     for( k=0; k<8; k++)    
  30.     {
  31.         str.Format("%d_", stmp[k]);
  32.         strs+=str;
  33.     }
  34.     m_listdata.SetItem(item, 1, 1, strl, NULL, 0, 0, 0);
  35.     m_listdata.SetItem(item, 2, 1, strr, NULL, 0, 0, 0);
  36.     m_listdata.SetItem(item, 3, 1, strf, NULL, 0, 0, 0);
  37.     m_listdata.SetItem(item, 4, 1, strk, NULL, 0, 0, 0);
  38.     m_listdata.SetItem(item, 5, 1, strs, NULL, 0, 0, 0);
  39. }

  40.   在插入数据的过程中,一定要核对数据,犹其是在DES加密过程中一些数据发生了变化,更需要提前保存下来!显示数据部分,鼠标点击显示相应的数据:

  41. void CDESDlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
  42. {
  43.     NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  44.     // TODO: Add your control notification handler code here
  45.     int m_nCurrentSel = pNMListView->iItem;
  46.     CString info;
  47.     info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,1));
  48.     GetDlgItem(IDC_EDIT7)->SetWindowText(info);
  49.     info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,2));
  50.     GetDlgItem(IDC_EDIT8)->SetWindowText(info);
  51.     info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,3));
  52.     GetDlgItem(IDC_EDIT9)->SetWindowText(info);
  53.     info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,4));
  54.     GetDlgItem(IDC_EDIT10)->SetWindowText(info);
  55.     info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,5));
  56.     GetDlgItem(IDC_EDIT11)->SetWindowText(info);
  57.     *pResult = 0;
  58. }
  就这样轻松实现了一个对8位字符进行DES加密的算法查看器!如果你在仍对DES存在疑惑的话,你可以查阅本人写的代码,如果你DES加密有不对的地方,不妨用这个试试!

可以与本人联系:xuwenq88@126.com
阅读(675) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~