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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分组密码模式: CTR模式(计数器模式)相关的知识,希望对你有一定的参考价值。

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模式(计数器模式)的主要内容,如果未能解决你的问题,请参考以下文章

对称加密算法常用的五种分组模式(ECB/CBC/CFB/OFB/CTR)

《图解密码技术》Chapter4:分组密码的主要模式

实现五种分组加密模式ECB,CBC,CFB,OFB,CTR

CBC和CTR模式下的AES

CBC和CTR模式下的AES

分组密码的五种工作模式