DES(ecb)加密
来源:互联网 发布:计算机网络就业 知乎 编辑:程序博客网 时间:2024/05/19 15:20
因为工作关系,涉及到了DES和3DES,查阅了部分博客,发现写的都有些差异,加密结果与现有的工具机密结果不对,所以整理了下。先介绍下对称密码算法DES。
DES算法具有极高安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。而56位长的密钥的穷举空间为256,这意味着如果一台计算机的速度是每一秒种检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间,可见,这是难以实现的,当然,随着科学技术的发展,当出现超高速计算机后,我们可考虑把DES密钥的长度再增长一些,以此来达到更高的保密程度。
先贴上代码
#include<memory.h>#include "DES.h"#include<stdio.h>char szKeys[16][48];//存储16组48bit密钥char szCipherText[64];//存储64位密文char szplaintText[64];//存储64位明文char szCiphertextInBytes[8];//储存8位密文char szPlaintextInBytes[8];//储存8位明文字符串char szCiphertextInBinary[65]; //储存二进制密文(64个Bits) char szCiphertextInHex[17]; //储存十六进制密文,最后一位存'\0'// permuted choice table (PC1)const static char PC1_Table[56] = {//64位密钥去掉8,16,24...等8位奇偶位,对PC1_Table进行置换,密钥A=0--27,57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, //B=28--56 [注:数字为数组下标]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};// permuted choice key (PC2)const static char PC2_Table[48] = {//A,B俩个28bit的密钥进行i次迭代后,组合成56bit密钥,对PC2_Table进行置换,14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,//生成子密钥,子密钥与进行i次迭代的数据进行位异或操作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};// number left rotations of pc1 const static char Shift_Table[16] = { //第i次迭代次数1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};// initial permutation (IP)const static char IP_Table[64] = {//明文数据对此表进行置换,得到新的64bit数据58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7};// expansion operation matrix (E)const static char E_Table[48] = {//把IP_Table置换过的明文数据分为left,right两部分,left不变,right对E_Table进行扩展,成48bit32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,//然后与i次迭代生成的子密钥进行位异或操作,得到新的right数据8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1};// The (in)famous S-boxes const static char S_Box[8][4][16] = {//把新的到的right48bit数据压缩成32bit,1.把48bit数据分割成8个6bit数据,// S12.把6bit的数据第1位和第6位组合位此表纵坐标,2-5位横坐标,得到相关值14, 4,13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,//3.把数据转为4bit S[i]对应i次迭代的数据0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,//4.最终得到32bit数据4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,// S2 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,// S3 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,// S4 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,// S5 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,// S6 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,// S7 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,// S8 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11};// 32-bit permutation function P used on the output of the S-boxes const static char P_Table[32] = {//将得到的32bit right数据按P_Table进行置换,得到新数据right16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,//将right与left进行位异或操作,结果赋值给right2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 //将本次的原始right值赋值给left};//得到的left和right进行下一次迭代操作// final permutation IP^-1 const static char IPR_Table[64] = {//将left和right结合,按IPR_Table表进行置换,结果为最终的加密数据40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25};extern "C" void initialization(){memset(szKeys, 0, 16 * 48);memset(szCipherText, 0, 64);memset(szplaintText, 0, 64);memset(szCiphertextInBytes, 0, 8);memset(szPlaintextInBytes, 0, 8);memset(szCiphertextInBinary, 0, 65);memset(szCiphertextInHex, 0, 17);}extern "C" char *DES_GetszCiphertextInBytes(){return szCiphertextInBytes;}extern "C" char *DES_GetszPlaintextInBytes(){return szPlaintextInBytes;}extern "C" void DES_InitializeKey(char* srcBytes){char sz_64key[64] = { 0 };char sz_56key[56] = { 0 };DES_Bytes2Bits(srcBytes, sz_64key, 64);for (int i = 0; i < 56; i++) //置换64位密钥为56位{sz_56key[i] = sz_64key[PC1_Table[i]-1];}DES_CreateSubKey(sz_56key);}extern "C" void DES_CreateSubKey(char* sz_56key){int i, j;char sz_leftKey[28] = { 0 };char sz_rightKey[28] = { 0 };char sz_tempL[28] = { 0 };char sz_tempR[28] = { 0 };char sz_temp56[56] = { 0 };memcpy(sz_leftKey, sz_56key, 28);memcpy(sz_rightKey, sz_56key+28, 28);for (i = 0; i < 16; i++){memcpy(sz_tempL, sz_leftKey + Shift_Table[i], 28 - Shift_Table[i]); //移位操作memcpy(sz_tempL + 28 - Shift_Table[i], sz_leftKey, Shift_Table[i]);memcpy(sz_tempR, sz_rightKey + Shift_Table[i], 28 - Shift_Table[i]);//移位操作memcpy(sz_tempR + 28 - Shift_Table[i], sz_rightKey, Shift_Table[i]);memcpy(sz_temp56, sz_tempL, 28);memcpy(sz_temp56+28, sz_tempR, 28);for (j = 0; j < 48; j++){szKeys[i][j] = sz_temp56[PC2_Table[j]-1]; //生成16组48位的子密钥}memcpy(sz_leftKey, sz_tempL, 28);memcpy(sz_rightKey, sz_tempR, 28);}}extern "C" void DES_EncryptData(char* _srcBytes) //加密8位字符串{int i = 0,j=0;char sz_srcBits[64] = { 0 };char sz_shiftIP[64] = { 0 };char sz_srcL[32] = { 0 };char sz_srcR[32] = { 0 };char sz_resultBits[64] = { 0 };DES_Bytes2Bits(_srcBytes, sz_srcBits, 64); for (i = 0; i < 64; i++){sz_shiftIP[i] = sz_srcBits[IP_Table[i]-1]; //64位明文置换}memcpy(sz_srcL, sz_shiftIP, 32);memcpy(sz_srcR, sz_shiftIP + 32, 32);for (i = 0; i<16; i++) //16次迭代操作{DES_FunctionF(sz_srcL, sz_srcR, i);}memcpy(sz_resultBits, sz_srcR, 32); //组合left、rightmemcpy(sz_resultBits + 32, sz_srcL, 32);for (j = 0; j<64; j++){szCipherText[j] = sz_resultBits[IPR_Table[j] - 1]; //进行逆置换}DES_Bits2Bytes(szCiphertextInBytes, szCipherText, 64);}extern "C" void DES_FunctionF(char* sz_srcL, char* sz_srcR, unsigned int iKey){int i = 0;char sz_P32[32] = { 0 };char sz_R[32] = { 0 };char sz_48R[48] = { 0 };char sz_key[48] = { 0 };char sz_xor[48] = { 0 };char compressData32[32] = { 0 };for (i = 0; i < 48; i++)//right 扩展{sz_48R[i] = sz_srcR[E_Table[i]-1];}memcpy(sz_key, szKeys[iKey], 48);DES_XOR(sz_48R, sz_key, 48, sz_xor); //扩展后的right与子密钥进行异或操作DES_CompressFunc(sz_xor, compressData32);//异或结果进行压缩成32bitfor (i = 0; i<32; i++){sz_P32[i] = compressData32[P_Table[i] - 1]; // 压缩后的数据进行置换}DES_XOR(sz_P32, sz_srcL, 32, sz_R); //置换后的right与left数据进行异或memcpy(sz_srcL, sz_srcR, 32); //传入的初始right赋值给left作为下次的leftmemcpy(sz_srcR, sz_R, 32);//左右异或生成的right的值作为下次运算的right}extern "C" void DES_XOR(char* szParam1, char* szParam2, unsigned int uiParamLength, char* szReturnValueBuffer)//异或操作{unsigned int i = 0;for (i = 0; i<uiParamLength; i++){szReturnValueBuffer[i] = szParam1[i] ^ szParam2[i];}}extern "C" void DES_CompressFunc(char* _src48, char* _dst32)//压缩数据{char tempBit[8][6] = { 0 };char dest4bit[4] = { 0 };int i = 0, X = 0, Y = 0, j = 0;for (i = 0; i<8; i++){memcpy(tempBit[i], _src48 + i * 6, 6);X = (tempBit[i][0] << 1 )+ (tempBit[i][5]);Y = 0;for (j = 1; j<5; j++){Y += tempBit[i][j] << (4 - j);}DES_Int2Bits(S_Box[i][X][Y], dest4bit);memcpy(_dst32 + i * 4, dest4bit, 4);}}extern "C" void DES_Bytes2Bits(char *srcBytes, char* dstBits, unsigned int sizeBits){unsigned int i = 0;for (i = 0; i < sizeBits; i++)dstBits[i] = ((srcBytes[i >> 3] << (i & 7)) & 128) >> 7;}extern "C" void DES_Bits2Bytes(char *dstBytes, char* srcBits, unsigned int sizeBits){unsigned int i = 0;memset(dstBytes, 0, sizeBits >> 3);for (i = 0; i < sizeBits; i++)dstBytes[i >> 3] |= (srcBits[i] << (7 - (i & 7)));}extern "C" void DES_Int2Bits(unsigned int _src, char* dstBits){unsigned int i = 0;for (i = 0; i < 4; i++)dstBits[i] = ((_src << i) & 8) >> 3;}extern "C" void DES_Bits2Hex(char *dstHex, char* srcBits, unsigned int sizeBits){unsigned int i = 0, j = 0;memset(dstHex, 0, sizeBits >> 2);for (i = 0; i < sizeBits; i++) //convert to int 0-15dstHex[i >> 2] += (srcBits[i] << (3 - (i & 3)));for (j = 0; j < (sizeBits >> 2); j++) dstHex[j] += dstHex[j] > 9 ? 55 : 48; //convert to char '0'-'F'} extern "C" void DES_Hex2Bits(char *srcHex, char* dstBits, unsigned int sizeBits){unsigned int i = 0, j = 0;memset(dstBits, 0, sizeBits);for (i = 0; i < (sizeBits >> 2); i++)srcHex[i] -= srcHex[i] > 64 ? 55 : 48; //convert to char int 0-15for (j = 0; j < sizeBits; j++)dstBits[j] = ((srcHex[j >> 2] << (j & 3)) & 15) >> 3;}extern "C" void DES_DecryptData(char* _srcBytes) //解密8位字符串{int i = 0, j = 0;char sz_srcBits[64] = { 0 };char sz_shiftIP[64] = { 0 };char sz_srcL[32] = { 0 };char sz_srcR[32] = { 0 };char sz_resultBits[64] = { 0 };DES_Bytes2Bits(_srcBytes, sz_srcBits, 64);for (i = 0; i < 64; i++){sz_shiftIP[i] = sz_srcBits[IP_Table[i] - 1]; }memcpy(sz_srcR, sz_shiftIP, 32);memcpy(sz_srcL, sz_shiftIP + 32, 32);for (i = 0; i<16; i++) {DES_FunctionF(sz_srcR, sz_srcL, 15 - i);}memcpy(sz_resultBits, sz_srcL, 32); memcpy(sz_resultBits + 32, sz_srcR, 32);for (j = 0; j<64; j++){szplaintText[j] = sz_resultBits[IPR_Table[j] - 1]; }DES_Bits2Bytes(szPlaintextInBytes, szplaintText, 64);}
一些概念就不多说了,网上一大堆
具体操作,上面注释已经说的差不多了,也就不多说了,只有几个注意的,置换表是按1开始算的,所以,我们置换的时候需要-1。还有就是一般我们使用的时候,都是16进制
的字符串进行加密,可以使用自己将8字节的字符串转为hex,就可以实现了。还有就是加密的结果用明文形式直接输出的话,会乱码,所以我们需要将它转为十六进制,或者
用base64进行转码(网上的一些在线工具,一般都是用了base64的,查看源码可以看到)。
然后就是关于解码问题,把right和left对换一下,因为right是上次的left和right异或的结果,而上次的right赋值给了left,所以调换下位置就行。keys从15开始。
代码借鉴了一位大佬的http://www.cnblogs.com/erwin/archive/2009/04/14/1435288.html,取来阅读理解了下。
有啥问题,欢迎指正。
1 0
- DES(ecb)加密
- DES-ECB加密与解密
- JAVA DES加密(DES/ECB/PKCS5Padding)和C#加密对应设置
- java DES ECB模式对称加密解密
- iOS DES ECB模式对称加密解密
- iOS DES ECB模式对称加密解密
- 3DES 和 ECB CBC 加密方式
- java DES ECB模式对称加密解密
- iOS DES ECB模式对称加密解密
- android java 3des加密 ECB/CBC
- DES加密,ECB和CBC区别
- 3DES 和 ECB CBC 加密方式
- python 实现DES加密 ECB模式
- iOS DES ECB模式对称加密解密
- 3DES 和 ECB CBC 加密方式
- PHP DES加密/解密 ECB 、pkcs5/pkcs7
- 3DES 和 ECB CBC 加密方式
- openssl c++ 3des ecb 加密
- JSON(对象数组,HashMap)
- php版本
- RecyclerView和EditText焦点冲突和输入法软键盘把布局顶出屏幕之外的解决
- HDU-5102-The K-th Distance【思维】【好题】
- Sass mixin
- DES(ecb)加密
- [BZOJ2788][Poi2012]Festival(差分约束+floyed+tarjan)
- Python性能分析
- C语言下程序的堆栈调用(详细,图示)
- POJ-1101_The Game
- 数据结构--平衡二叉树的插入详解
- Codeforces 801D Volatile Kite 几何
- 关于synchronized(object){//} 同步代码块
- 如何用abaqus建造8号槽钢并分析槽钢的受力