找回密码
 注册
搜索
查看: 1133|回复: 3

[综合资料] 一个MTK平台可以使用的DES加密算法

[复制链接]
发表于 2009-3-9 19:39:29 | 显示全部楼层 |阅读模式
前段时间写一个网络支付的程序,需要把客户信息和帐号信息加密发送,由于需要对称加密,所以采用了DES算法,大致在25平台上计算了一下时间,大约需要50到60TICK,大概在200和300毫秒之间。
主要提供两个接口,一个加密MessagePaymentDesEncrypt一个解密:MessagePaymentDesDecrypy,加密的参照数据是网上找来的,应该是一种标准,可能有些可以改。
/**********************************************************************************/
/*DES加密数据>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/**********************************************************************************/
//DES加密常量数据start
/***************************************************************************************
* 函数名称: ByteToBit
* 功能描述: 把8个字节的输入转为64个Bit的输出,标准DES定义
* 参数说明: In:     待处理字串
*           Out:    处理后的字串
*           bits:   In的长度
*           
* 函数类型:
* 返回值:   NULL
* 其他说明:
***************************************************************************************/
void ByteToBit(S8 *Out, const S8 *In, U8 bits)
{
    U8 i;

    for(i=0; i<bits; i++)
    {
        Out = (In[i/8]>>(i%8)) & 1;
    }
}
/***************************************************************************************
* 函数名称: Transform
* 功能描述: 按Table要求调整待处理字符串的位置
* 参数说明: In:     待处理字串
*           len:    密钥字串的长度
*           Table:  已经定义的长量数组
*           len:    待处理字串长度
* 函数类型:
* 返回值:   NULL
* 其他说明: Table要使用标准数组
***************************************************************************************/
void Transform(S8 *Out, S8 *In, const S8 *Table, U8 len)
{
    S8 Tmp[256];
    U8 i;

    for(i = 0; i < len; i++)
    {
        Tmp = In[Table-1];
    }
    memcpy(Out, Tmp, len);
}
/***************************************************************************************
* 函数名称: RotateL
* 功能描述: 设置DES的待处理字串循环换位,DES标准
* 参数说明: In:     待处理字串
*           len:    密钥字串的长度
*           loop:   换位控制
* 函数类型:
* 返回值:   NULL
* 其他说明: loop要使用标准数组
***************************************************************************************/
void RotateL(S8 *In, U8 len, S8 loop)
{
    S8 Tmp[256];
   
    memcpy(Tmp, In, loop);
    memcpy(In, In+loop, len-loop);
    memcpy(In+len-loop, Tmp, loop);
}
/***************************************************************************************
* 函数名称: DesSetKey
* 功能描述: 设置DES的密钥
* 参数说明: keystr:    密钥字串
*           strlen:    密钥字串的长度
*         
* 函数类型:
* 返回值:   NULL
* 其他说明: 密钥设置一般为长度8个字节的字串
***************************************************************************************/

void DesSetKey(PS8 keystr, U8 strlen, S8 (*SubKey)[16][48])
{
    S8 K[64], *KL = &K[0], *KR = &K[28];
    U8 i;
    // 提取除校验位外的混合后密码的56BIT
    const S8 PC1_Table[56] = {
        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
        };
    // number left rotations of pc1
    const S8 LOOP_Table[16] = {
        1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
        };

    // 提取除校验位外的混合后密码的48BIT
    const S8 PC2_Table[48] = {
        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
        };

    ByteToBit(K, keystr, 64);   //获取密码串的各BIT位
    Transform(K, K, PC1_Table, 56);    //按PC1_Table交换各BIT位置到得新的BIT位数据
    for(i=0; i<16; i++)
    {
        RotateL(KL, 28, LOOP_Table);    //对KL循环移位
        RotateL(KR, 28, LOOP_Table);
        Transform((*SubKey), K, PC2_Table, 48);      //生成16圈的密钥SubKey
    }
}
/***************************************************************************************
* 函数名称: Xor
* 功能描述: 执行两数组的异或运算
* 参数说明: inA:     待处理的字串
*           InB:     处理好的字串
*           len:     运算长度
* 函数类型:
* 返回值:   NULL
* 其他说明:
***************************************************************************************/
void Xor(S8 *InA, const S8 *InB, U8 len)
{
    U8 i;

    for(i = 0; i < len; i++)
    {
        InA ^= InB;
    }
}
/***************************************************************************************
* 函数名称: S_func
* 功能描述: 使用SBOX处理In字串,这是DES标准
* 参数说明: in:     待处理的字串
*           OUT:    处理好的字串
*   
* 函数类型:
* 返回值:   NULL
* 其他说明:
***************************************************************************************/

void S_func(S8 Out[32], const S8 In[48])
{
    S8 i, j, k;
    // The (in)famous S-boxes
    const S8 S_Box[8][4][16] = {
        // S1
        14,     4,    13,     1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
        0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
        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
        };

    for(i=0; i<8; i++,In+=6,Out+=4)
    {
        j = (In[0]<<1) + In[5];
        k = (In[1]<<3) + (In[2]<<2) + (In[3]<<1) + In[4];
        ByteToBit(Out, &S_Box[j][k], 4);
    }
}
/***************************************************************************************
* 函数名称: F_func
* 功能描述: 使用KI加密In字串
* 参数说明: in:     待处理的字串
*           Ki:     密钥
*   
* 函数类型:
* 返回值:   NULL
* 其他说明:
***************************************************************************************/
void F_func(S8 In[32], const S8 Ki[48])
{
    S8 MR[48];
    // expansion operation matrix
    const S8 E_Table[48] = {
    32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
    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
    };
    const S8 P_Table[32] = {
    16, 7, 20, 21, 29, 12, 28, 17, 1,  15, 23, 26, 5,  18, 31, 10,
    2,  8, 24, 14, 32, 27, 3,  9,  19, 13, 30, 6,  22, 11, 4,  25
    };

    Transform(MR, In, E_Table, 48);
    Xor(MR, Ki, 48);
    S_func(In, MR);
    Transform(In, In, P_Table, 32);
}
/***************************************************************************************
* 函数名称: BitToByte
* 功能描述: 把BIT位数组合成字节数组
* 参数说明: in:     待处理的字串
*           out:    目标字串
*           bits:   In字符串的长度
* 函数类型:
* 返回值:   NULL
* 其他说明: bits取值一般为64
***************************************************************************************/
void BitToByte(PS8 Out, const S8 *In, U8 bits)
{
    U8 i;

    memset(Out, 0, (bits+7)/8);
    for(i=0; i<bits; i++)
    {
        Out[i/8] |= In<<(i%8);
    }
}
/***************************************************************************************
* 函数名称: Des_Run
* 功能描述: 标准DES加解密函数
* 参数说明: in:     待处理的字串
*           out:    目标字串
*           type:   用来区分加密还是解密,取值为枚举:ENCRYPT,加密; DECRYPT,解密
* 函数类型:
* 返回值:   NULL
* 其他说明: 按DES标准该函数只支持8个字节的字符加密,且在调用前需要调用函数
*           DesSetKey设置密钥
***************************************************************************************/
void Des_Run(S8 Out[8], S8 In[8], U8 Type, S8 (*SubKey)[16][48])
{
    S8 M[64], Tmp[32], *Li = &M[0], *Ri = &M[32];
    signed char i;
    // initial permutation IP
    const S8 IP_Table[64] = {
        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
        };

    // final permutation IP^-1
    const char IPR_Table[64] = {
        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
        };

    ByteToBit(M, In, 64);      //取出明文每个BIT的值到M中
    Transform(M, M, IP_Table, 64);    //把M中各值按IP_TABLE交换位置

    if(Type == ENCRYPT)         //加密过程
    {
        for(i=0; i<16; i++)
        {
            memcpy(Tmp, Ri, 32);
            F_func(Ri, (*SubKey));
            Xor(Ri, Li, 32);
            memcpy(Li, Tmp, 32);
        }
    }
    else                        //解密过程
    {
        for(i=15; i>=0; i--)
        {
            memcpy(Tmp, Li, 32);
            F_func(Li, (*SubKey));
            Xor(Li, Ri, 32);
            memcpy(Ri, Tmp, 32);
        }
    }
    Transform(M, M, IPR_Table, 64);
    BitToByte(Out, M, 64);
}

/***************************************************************************************
* 函数名称: DesEncrypt
* 功能描述: 加密字串
* 参数说明: srcstr:    待处理的字串
*           desstr:    目标字串
*           IsEncrypt: 用来区分加密还是解密,取值为枚举:ENCRYPT,加密; DECRYPT,解密
* 函数类型:
* 返回值:   desstr:加密或者解密后的字串
* 其他说明: 如果参数IsEncrypt为ENCRYPT,其desstr字串长度要比srcstr大且为8的整数倍
*           SRC不足八位或者不是8的整数倍,使用0x00补足八位
***************************************************************************************/
PS8 DesEncrypt(PS8 srcstr, PS8 desstr, U8 IsEncrypt)
{
    PS8 psrc, pdes;
    S8 tmpstr[9] = {0};
    U8 srclen;
    S8 SubKey[16][48] = {0};   //保存生成的加密密钥
    PS8 key = "12345678\0";  //设置的密码


    DesSetKey(key, strlen(key), &SubKey);   //设置密钥

    SCI_ASSERT((srcstr != NULL) && (desstr != NULL));
    srclen = strlen(srcstr);
    SCI_ASSERT(srclen != 0);

    psrc = srcstr;
    pdes = desstr;

    if (srclen > 8)
    {
        while (srclen > 0)
        {
            if (srclen <= 8)
            {
                memset(tmpstr, 0x00, sizeof(tmpstr));
                memcpy(tmpstr, psrc, strlen(psrc));
                Des_Run(tmpstr, tmpstr, IsEncrypt, &SubKey);
                memcpy(pdes, tmpstr, 8);
                srclen = 0;
            }
            else
            {
                memset(tmpstr, 0x00, sizeof(tmpstr));
                memcpy(tmpstr, psrc, 8);
                Des_Run(tmpstr, tmpstr, IsEncrypt, &SubKey);
                memcpy(pdes, tmpstr, 8);
                pdes += 8;
                psrc += 8;
                srclen = srclen - 8;
            }
        }
    }
    else
    {
        Des_Run(tmpstr, srcstr, IsEncrypt, &SubKey);
        memcpy(desstr, tmpstr, 8);
    }
    return desstr;
}
/***************************************************************************************
* 函数名称: MessagePaymentDesEncrypt
* 功能描述: 用来对给服务器发送的数据加密
* 参数说明: in:     待加密的字串
*           out:    加密后的字串
*           
* 函数类型:
* 返回值:   desstr:加密或者解密后的字串
* 其他说明: 按照DES标准OUT字串长度要比in大且为8的整数倍,
*           加密过程会自动把IN后加0x00使in和out长度一致
***************************************************************************************/

PS8 MessagePaymentDesEncrypt(PS8 in, PS8 out)
{
    return DesEncrypt(in, out, ENCRYPT);
}
/***************************************************************************************
* 函数名称: MessagePaymentDesDecrypy
* 功能描述: 用来对给服务器发送的数据解密
* 参数说明: in:    待解密的数据
*           out:   解密后的数据
*           
* 函数类型:
* 返回值:   desstr:加密或者解密后的字串
* 其他说明: in和out长度应该一样,防止数据溢出导致解密出错
***************************************************************************************/

PS8 MessagePaymentDesDecrypy(PS8 in, PS8 out)
{
    return DesEncrypt(in, out, DECRYPT);
}
 楼主| 发表于 2009-3-10 21:19:24 | 显示全部楼层
呵呵,没人顶,自己顶一下
点评回复

使用道具 举报

发表于 2009-3-13 16:33:36 | 显示全部楼层
有点意思
点评回复

使用道具 举报

发表于 2011-10-28 23:47:27 | 显示全部楼层
好东东,要试一试,谢谢啦
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-11-30 08:22 , Processed in 0.046050 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表