码迷,mamicode.com
首页 > 其他好文 > 详细

分组密码模式: CTR模式(计数器模式)

时间:2016-05-25 00:25:35      阅读:2062      评论:0      收藏:0      [点我收藏+]

标签:

CTR模式是一种通过将逐次累加的计数器进行加密来生成密钥流的流密码,在CTR模式中,每个分组对应一个逐次累加的计数器,并通过对计数器进行加密来生成密钥流。最终的密文分组是通过将计数器加密得到的比特序列与明文分组进行XOR而得到的,如下图所示:

技术分享

技术分享

计数器的生成方法如下图所示:

技术分享

CTR模式和OFB模式一样,都属于流密码。如果我们将单个分组的加密过程拿出来,那么OFB模式和CTR模式之间的差异还是很容易理解的:

技术分享

 

CTR模式的加密:

#include <STRING.H>

#define IN
#define OUT

//假设加密分组为4字节一组

/**************************************************************************
*功  能:    加密算法 (与Key异或)
*参  数:    lpszData        当前明文分组数据
*           lpszKey         Key    
*           lpszDeData      加密后的结果
*
*返回值:    
**************************************************************************/
void Encrypt(IN const char *lpszData, IN const char *lpszKey, OUT char *lpszEnData)
{
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        lpszEnData[i] = lpszData[i] ^ lpszKey[i];
    }
}

/**************************************************************************
*功  能:    当前明文与当前密钥流异或
*参  数:    lpszData        当前明文分组数据
*           lpszKeyStream   当前密码算法的输出
*           lpszXorData     保存异或后的数据
*
*返回值:    
**************************************************************************/
void XorData(IN const char *lpszData, IN const char *lpszKeyStream, OUT char *lpszXorData)
{
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        lpszXorData[i] = lpszData[i] ^ lpszKeyStream[i];
    }
}

int main(int argc, char* argv[])
{
    char szData[] = "Hello World!";
    char szEnData[16] = {0};
    char szDeData[16] = {0};
    char *lpszKey = "1234";
    int i = 0;
    char szCTR[] = {0x39, 0x39, 0x39, 0x01};      //假设最后一个字节为计数器
    char szCTREnData[8] = {0};

    printf("原始数据: %s\r\n", szData);
    
    while (true)
    {
        if (strlen(szData + i) == 0)
        {
            break;
        }

        //当前计数器与加密算法加密
        Encrypt(szCTR, lpszKey, szCTREnData);

        //明文分组与上面加密后的值做异或操作
        XorData(szData + i, szCTREnData, szEnData + i);
        
        //更新当前计数器的值
        szCTR[3] += 1;

        i += 4;
    }
    
    printf("加密后数据: %s\r\n", szEnData);
    
    char szTmp[] = {0x39, 0x39, 0x39, 0x01}; 
    memcpy(szCTR, szTmp, 4);
    i = 0;
    
    while (true)
    {
        if (strlen(szEnData + i) == 0)
        {
            break;
        }
        
        //当前计数器与加密算法加密
        Encrypt(szCTR, lpszKey, szCTREnData);

        //密文分组与上面加密后的值做异或操作
        XorData(szEnData + i, szCTREnData, szDeData + i);

        //更新当前计数器的值
        szCTR[3] += 1;

        i += 4;
    }
    
    printf("解密后数据: %s\r\n", szDeData);
    
    return 0;
}

原始数据: Hello World!
加密后数据: @nfYg+]Yzgn
解密后数据: Hello World!

.

分组密码模式: CTR模式(计数器模式)

标签:

原文地址:http://www.cnblogs.com/dacainiao/p/5525410.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!