RC4加密

简介

在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一。 由美国密码学家罗纳德·李维斯特(Ronald Rivest)在1987年设计的。由于RC4算法存在弱点,2015年2月所发布的 RFC 7465 规定禁止在TLS中使用RC4加密算法。

原理

RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。 由于异或运算的对合性,RC4加密解密使用同一套算法。
初始化长度为256的S盒。第一个for循环将0到255的互不重复的元素装入S盒。第二个for循环根据密钥打乱S盒。

 for i from 0 to 255
     S[i] := i
 endfor
 j := 0
 for( i=0 ; i<256 ; i++)
     j := (j + S[i] + key[i mod keylength]) % 256
     swap values of S[i] and S[j]
 endfor
下面i,j是两个指针。每收到一个字节,就进行while循环。通过一定的算法((a),(b))定位S盒中的一个元素,并与输入字节异或,得到k。循环中还改变了S盒((c))。如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文。
 i := 0
 j := 0
 while GeneratingOutput:
     i := (i + 1) mod 256   //a
     j := (j + S[i]) mod 256 //b
     swap values of S[i] and S[j]  //c
     k := inputByte ^ S[(S[i] + S[j]) % 256]
     output K
 endwhile
此算法保证每256次循环中S盒的每个元素至少被交换过一次。

代码实现

  • c语言版
#ifndef _SYS_CRYPTO_RC4_RC4_H_
#define _SYS_CRYPTO_RC4_RC4_H_

struct rc4_state {
    u_char  perm[256];
    u_char  index1;
    u_char  index2;
};

extern void rc4_init(struct rc4_state *state, const u_char *key, int keylen);
extern void rc4_crypt(struct rc4_state *state,
        const u_char *inbuf, u_char *outbuf, int buflen);

#endif


#include <sys/types.h>
#include <crypto/rc4/rc4.h>

static __inline void
swap_bytes(u_char *a, u_char *b)
{
    u_char temp;

    temp = *a;
    *a = *b;
    *b = temp;
}

/*
 * Initialize an RC4 state buffer using the supplied key,
 * which can have arbitrary length.
 */
void
rc4_init(struct rc4_state *const state, const u_char *key, int keylen)
{
    u_char j;
    int i;

    /* Initialize state with identity permutation */
    for (i = 0; i < 256; i++)
        state->perm[i] = (u_char)i; 
    state->index1 = 0;
    state->index2 = 0;

    /* Randomize the permutation using key data */
    for (j = i = 0; i < 256; i++) {
        j += state->perm[i] + key[i % keylen]; 
        swap_bytes(&state->perm[i], &state->perm[j]);
    }
}

/*
 * Encrypt some data using the supplied RC4 state buffer.
 * The input and output buffers may be the same buffer.
 * Since RC4 is a stream cypher, this function is used
 * for both encryption and decryption.
 */
void
rc4_crypt(struct rc4_state *const state,
    const u_char *inbuf, u_char *outbuf, int buflen)
{
    int i;
    u_char j;

    for (i = 0; i < buflen; i++) {

        /* Update modification indicies */
        state->index1++;
        state->index2 += state->perm[state->index1];

        /* Modify permutation */
        swap_bytes(&state->perm[state->index1],
            &state->perm[state->index2]);

        /* Encrypt/decrypt next byte */
        j = state->perm[state->index1] + state->perm[state->index2];
        outbuf[i] = inbuf[i] ^ state->perm[j];
    }
}

 int main(int argc, char* argv[]){

    int dataLength = 8;
    int keyLength = 8;
    const unsigned char dataStream[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
    printf("before\n");
    for (int i = 0; i < dataLength ; i++) {
        printf("%x,",dataStream[i]);
    }
    printf("\n");
    unsigned char encryp[dataLength];
    unsigned char decryp[dataLength];
    unsigned char key[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
    struct rc4_state state;

    rc4_init(&state, key, keyLength);// this code is very important

    rc4_crypt(&state, dataStream, encryp, dataLength);
    printf("\nencrypt\n");
    for (int i = 0; i < dataLength ; i++) {
        printf("%x,",encryp[i]);
    }
    printf("\nafter \n");
    rc4_init(&state, key, keyLength);// this code is very important
    rc4_crypt(&state, encryp, decryp, dataLength);
    for (int i = 0; i < dataLength ; i++) {
        printf("%x,",decryp[i]);
    }
    printf("\n");
    return 0;
}
  • c++版
// RC4.cpp : 定义控制台应用程序的入口点。
//
//-----------------RC4加密算法------------------------------------

//头文件声明
#include "stdafx.h"
#include<iostream>
#include<string>

using namespace std;

//函数声明
void swap_value(int &a, int &b);
void init_s(string k);
void display(int S[], int len);
string output(string input);


//显示s盒子的内容
void display(int S[], int len)
{
    cout<<"S[]:"<<endl;
    for (int i = 0; i < len; i++)
    {
        cout<<S[i]<<'\t';
    }
}

/*
----------【1】产生S盒子--------------------------------------
初始化长度为256的S盒。第一个for循环将0到255的互不重复的元素装入S盒。
第二个for循环根据密钥打乱S盒。
伪代码
 for i from 0 to 255
     S[i] := i
 endfor
 j := 0
 for( i=0 ; i<256 ; i++)
     j := (j + S[i] + key[i mod keylength]) % 256
     swap values of S[i] and S[j]
 endfor
*/
int S[256] = {0};

void init_s(string k)
{
    for (int i = 0; i < 256; i++)
    {
        S[i] = i;
    }
    int j = 0;
    for (int i = 0; i < 256; i++)
    {
        j = (j+S[i]+int(k[i%k.length()]))%256;//得到j的算法
        swap_value(S[i],S[j]);
    }
}

//字符转换为asscii码值
int chage_to_asc(char c)
{
    return int(c);
}
/*
----------------【2】加密解密----------------------------------------
下面i,j是两个指针。每收到一个字节,就进行while循环。通过一定的算法((a),(b))
定位S盒中的一个元素,并与输入字节异或,得到k。循环中还改变了S盒((c))。
如果输入的是明文,输出的就是密文;
如果输入的是密文,输出的就是明文。
伪代码
 i := 0
 j := 0
 while GeneratingOutput:
     i := (i + 1) mod 256   //a
     j := (j + S[i]) mod 256 //b
     swap values of S[i] and S[j]  //c
     k := inputByte ^ S[(S[i] + S[j]) % 256]
     output K
 endwhile
 */
string output(string input)
{
    int i = 0;
    int j = 0;
    int k;
    string output = input;
    for (int t= 0; t< input.length(); t++)
    {
        i = (i+1)%256;
        j = (j+S[i])%256;
        swap_value(S[i], S[j]);
        k = int(input[t])^S[ (S[i] + S[j])%256 ];
        output[t] = char(k);
    }
    return output;
}


//交换两个变量值
void swap_value(int &a, int &b)
{
    int temp = 0;
    temp = a;
    a = b;
    b = temp;
}


int _tmain(int argc, _TCHAR* argv[])
{
    //密钥、明文、密文
    string k,m,c;

    //【1】输入明文和密钥
    cout<<"input the m"<<endl;
    cin>>m;

    cout<<"input the k:"<<endl;
    cin>>k;

    //【2】初始化S盒子
    init_s(k);

    //【3】产生输出
    c = output(m);
    cout<<c<<endl;

    //【2】初始化S盒子
    init_s(k);

    //【3】产生输出
    m = output(c);
    cout<<m<<endl;
    //display(S, 256);
    return 0;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mango_haoming/article/details/78463335
文章标签: 密码学 算法 加密
个人分类: c/c++ 数据结构
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭