RC4加密算法分析

February 26, 2019 逆向 访问: 23 次

简介

在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一

关键变量

  1. 秘钥流:RC4算法的关键是依据明文和秘钥生成相应的秘钥流,密钥流的长度和明文的长度是相应的,也就是说明文的长度是500字节,那么密钥流也是500字节。他们之间符合一个公式
密文[i]=明文[i]^密钥流[i]
  1. 状态向量S:长度为256.S[0]、S[1]……S[255]。每个单元都是一个字节。无论算法执行到什么时候,S都包含0~255的数字,变化的仅仅是每个数字的在这个数组中的位置

  2. 暂时向量T:长度也是256,每个单元是一个字节。这个向量的内容是将key循环的赋值到这个数组当中

  3. 密钥key:长度位1~256个字节。密钥的长度与明文长度、密钥流长度没有必定关系。

原理

  1. 初始化向量S和向量T
void rc4_init(uint8_t *s, uint8_t *key , uint16_t Len)
{
    int i =0, j = 0;
    char k[256] = {0};
    uint8_t tmp = 0;
    for (i=0;i<256;i++) {
        s[i] = i;
        k[i] = key[i%Len];
    }
    printf("------------转变前数组s------------\n");
    for(i=0;i<256;i++)
    {
        printf("%d ", s[i]);
    }
    printf("\n------------数组k------------\n");
    for(i=0;i<256;i++)
    {
        printf("%c ", k[i]);
    }
}
  1. 初始化排列S
    for (i=0; i<256; i++) {
        j=(j+s[i]+k[i])%256;
        tmp = s[i];
        s[i] = s[j]; //交换s[i]和s[j]
        s[j] = tmp;
    }
    printf("\n------------数组s------------\n");
    for(i=0;i<256;i++)
    {
        printf("%d ", s[i]);
    }
  1. 产生密钥流
    for(k=0;k<Len;k++)
    {
        i = (j+1)%256;
        j = (j+s[i])%256;
        //printf("\ni:%d,j:%d\n",i,j );
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
        t = (s[i]+s[j])%256;
        k[k]= s[t];
    }
  1. 密钥流和明文异或
for(i=0;i<len(明文);i++)
{
    密文[i]=明文[i]^密钥流[i];
}

解密与解密脚本(C语言):

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
void rc4_init(uint8_t *s, uint8_t *key , uint16_t Len)
{
    int i =0, j = 0;
    char k[256] = {0};
    uint8_t tmp = 0;
    for (i=0;i<256;i++) {
        s[i] = i;
        k[i] = key[i%Len];
    }
    printf("------------数组s------------\n");
    for(i=0;i<256;i++)
    {
        printf("%d ", s[i]);
    }
    printf("\n------------数组k------------\n");
    for(i=0;i<256;i++)
    {
        printf("%c ", k[i]);
    }
    for (i=0; i<256; i++) {
        j=(j+s[i]+k[i])%256;
        tmp = s[i];
        s[i] = s[j]; //交换s[i]和s[j]
        s[j] = tmp;
    }
    printf("\n------------数组s------------\n");
    for(i=0;i<256;i++)
    {
        printf("%d ", s[i]);
    }
}
void rc4_crypt(uint8_t *s,uint8_t *Data, uint16_t Len)
{
    int i=0,j=0,t=0;
    uint16_t k=0;
    uint8_t tmp;
    for(k=0;k<Len;k++)
    {
        i = (j+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(int argc,char ** argv){
    char date[9] = {};
    uint8_t s[256] = {0}; //S-box
    uint8_t flagLen = 0,j=0,i;
    char key[9] = "";
    rc4_init(s,(uint8_t *)key, strlen(key)); //初始化密钥
    rc4_crypt(s,(uint8_t *)enc,strlen(enc)); //解密
    printf("\n下面是密文:\n");
    for(j=0;j<10;j++){
        printf("%d ", enc[j]);
    }
}

添加新评论