山川异域,风月同钉——你知道你的网课直播视频是怎么加密的吗?

疫情期间绝大多数学生都待在家上网课,钉钉也是趁势火了一把,甚至流传出了“山川异域,风月同钉”的梗。相信很多人都收到过钉钉“你收到一条加密信息”的提醒,这句话也流传出了很多的表情包。其实钉钉除了消息会在服务端经过加密处理再发送到客户端以外,我们平常上网课的视频直播也是经过加密再送到学生端的。而与文字信息加密不同的是,视频直播是连续实时并且信息量巨大的,这个特点直接导致很多经典的加密算法比如DES、AES很难达到视频直播加密所要求的加密速度。这时我们就要用到一种特殊的加密算法——RC4加密算法了。
RC4是一种流加密算法,其主要用途是对视频流进行在线加密,优点是加密速度快,可以达到DES加密算法速度的10倍,缺点当然是安全性不高,容易被破解。对于视频直播而言,加密强度并不是首位的,提高加密效率、降低延迟往往是最重要的。
RC4加密的算法非常简单,如果使用C语言写的话只需要几十行,网上关于RC4加密算法的代码也非常多,这里我以百度百科中的C语言示例代码为例讲解一下RC4加密算法的加密流程。
首先附上百度百科的链接和完整代码
https://baike.baidu.com/item/RC4/3454548?fr=aladdin

#include<stdio.h>
#include<string.h>
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{
    int i = 0, j = 0;
    char k[256] = { 0 };
    unsigned char tmp = 0;
    for (i = 0; i<256; i++)
    {
        s[i] = i;
        k[i] = key[i%Len];
    }
    for (i = 0; i<256; i++)
    {
        j = (j + s[i] + k[i]) % 256;
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
}

void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{
    int i = 0, j = 0, t = 0;
    unsigned long k = 0;
    unsigned char tmp;
    for (k = 0; k<Len; k++)
    {
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
        t = (s[i] + s[j]) % 256;
        Data[k] ^= s[t];
    }
}
 
int main()
{
    unsigned char s[256] = { 0 }, s2[256] = { 0 };
    char key[256] = { "ig_jdg_fpx_tes_estar_edg_rng_we" };
    char text[512] = "山川异域,风月同钉;ig季后赛冲冲冲!期待ig与tes的对决!" ;
    unsigned long len = strlen(text);
    int i;
 
    printf("加密前明文为:\t%s\n", text);
    rc4_init(s, (unsigned char*)key, strlen(key));
    for (i = 0; i<256; i++)
    {
        s2[i] = s[i];
    }
    rc4_crypt(s, (unsigned char*)text, len);
    printf("加密后密文为:\t%s\n", text);
    rc4_crypt(s2, (unsigned char*)text, len);
    printf("解密后明文为:\t%s\n", text);
    return 0;
}

接下来我们来详细讲解一下这段程序
RC4加密算法的密钥最大长度为256字节,也就是100H
程序的开始会进行密钥的初始化
首先定义了一个unsigned char类型的数组s和一个char类型的数组k,长度均为256。在rc4_init函数中,首先对数组s和数组k进行初始化设置,使得
s[i] = i;
k[i] = key[i%Len];
其中Len是密钥的长度
对应的代码为

 for (i = 0; i<256; i++)
    {
        s[i] = i;
        k[i] = key[i%Len];
    }

从上面这段代码我们也能看出来,如果密钥的长度大于256,其256字节之后的内容是没有参与加密过程的,所以密钥的有效长度最大只有256字节
初始化之后,s[i] = i;
下面就要进行密钥的打乱工作了
对应的代码为

 for (i = 0; i<256; i++)
    {
        j = (j + s[i] + k[i]) % 256;
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }

从这段程序中我们可以看出来,其核心思想就是s数组的打乱,完成这256个循环之后,s中的元素仍然为0-255,每个数据出现且仅出现一次,但是已经不满足s[i] = i的顺序了
运行完rc4_init函数之后,就可以开始加密了
加密过程其实主要也是密钥的重新打乱,我们来看下面这段加密函数的代码

for (k = 0; k<Len; k++)
    {
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
        t = (s[i] + s[j]) % 256;
        Data[k] ^= s[t];
    }

这个for循环的主体有7行,其中前6行都还是在做打乱密钥的工作,通过不断的打乱顺序并且密钥元素的运算得到一个下标t,真正的加密其实只是Data[k]与s[t]进行异或运算这一条语句,大量的运算都是在打乱s数组
加密完成之后就可以输出密文了
因为异或运算本身是可逆运算,也就是A与B异或生成C,那么C与B异或又会得到A,所以RC4算法的加密和解密过程其实是一样的,因为最终动到Data的操作只是一个简单的异或而已
介绍完加密算法,我们来看一下运行效果
在这里插入图片描述
从上图可以看到,RC4加密算法是可以完成字符串的加密的
除了字符串和视频的加密,其实RC4也可以进行文件的加密,毕竟文件也可以有文件流嘛,这个大家可以自行实现一下,只要加一个函数就好了。我经过测试RC4的算法效率的确是很高,之前使用RSA加密算法对一个78M的文件进行加密,需要8s,解密需要134s,使用RC4进行加密解密都是1s以内完成的。
今天的讲解就到这里。

发布了5 篇原创文章 · 获赞 0 · 访问量 326

猜你喜欢

转载自blog.csdn.net/weixin_44735156/article/details/105689288