欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RC4算法

程序员文章站 2022-07-09 10:27:23
...

RC4是一种对称密码算法,它属于对称密码算法中的序列密码(streamcipher,也称为流密码),它是可变**长度,面向字节操作的流密码。
RC4是流密码streamcipher中的一种,为序列密码。RC4加密算法是Ron Rivest在1987年设计出的**长度可变的加密算法簇。起初该算法是商业机密,直到1994年,它才公诸于众。由于RC4具有算法简单,运算速度快,软硬件实现都十分容易等优点,使其在一些协议和标准里得到了广泛应用。
流密码也属于对称密码,但与分组加密算法不同的是,流密码不对明文数据进行分组,而是用**生成与明文一样长短的密码流对明文进行加密,加解密使用相同的**。
RC4算法特点:(1)、算法简洁易于软件实现,加密速度快,安全性比较高;(2)、**长度可变,一般用256个字节。
对称密码算法的工作方式有四种:电子密码本(ECB, electronic codebook)方式、密码分组链接(CBC, cipherblock chaining)方式、密文反馈(CFB, cipher-feedback)方式、输出反馈(OFB, output-feedback)方式。
RC4算法采用的是输出反馈工作方式,所以可以用一个短的**产生一个相对较长的**序列。
OFB方式的最大的优点是消息如果发生错误(这里指的是消息的某一位发生了改变,而不是消息的某一位丢失),错误不会传递到产生的**序列上;缺点是对插入攻击很敏感,并且对同步的要求比较高。
RC4的执行速度相当快,它大约是分块密码算法DES的5倍,是3DES的15倍,且比高级加密算法AES也快很多。RC4算法简单,实现容易。RC4的安全保证主要在于输入**的产生途径,只要在这方面不出现漏洞,采用128bit的**是非常安全的。
RC4算法加密流程:包括**调度算法KSA和伪随机子密码生成算法PRGA两大部分(以**长度为256个字节为例)。
**调度算法:首先初始化状态矢量S,矢量S中元素的值被按升序从0到255排列,即S[0]=00, S[1]=1, …, S[255]=255.同时建立一个临时矢量T,如果**K的长度为256字节,则将K赋给T。否则,若**长度为keylen字节,则将K的值赋给T的前keylen个元素,并循环重复用K的值赋给T剩下的元素,直到T的所有元素都被赋值。

#include <stdio.h>
#define MAX_CHAR_LEN 10000

void produceKeystream(int textlength, unsigned char key[],
    int keylength, unsigned char keystream[])
{
    unsigned int S[256];
    int i, j = 0, k;
    unsigned char tmp;

    for (i = 0; i<256; i++)
        S[i] = i;
    for (i = 0; i<256; i++) {
        j = (j + S[i] + key[i % keylength]) % 256;
        tmp = S[i];
        S[i] = S[j];
        S[j] = tmp;
    }

    i = j = k = 0;
    while (k < textlength) {
        i = (i + 1) % 256;
        j = (j + S[i]) % 256;
        tmp = S[i];
        S[i] = S[j];
        S[j] = tmp;
        keystream[k++] = S[(S[i] + S[j]) % 256];
    }
}

void encrypt(int textlength, unsigned char plaintext[],
    unsigned char keystream[],
    unsigned char ciphertext[])
{
    int i;
    for (i = 0; i<textlength; i++)
        ciphertext[i] = keystream[i] ^ plaintext[i];
}

int main(int argc, char* argv[])
{
    if (argc != 2) {
        printf("Please use one and only one filename as a parameter\n");
        return 0;
    }

    unsigned char plaintext[MAX_CHAR_LEN];
    unsigned char key[32];
    unsigned char keystream[MAX_CHAR_LEN];
    unsigned char ciphertext[MAX_CHAR_LEN];
    unsigned c;
    int i = 0, textlength, keylength;
    FILE *fp;

    if ((fp = fopen(*++argv, "r")) == NULL) {
        printf("file \"%s\" not found!\n", *argv);
        return 0;
    }

    while ((c = getc(fp)) != EOF)
        plaintext[i++] = c;
    textlength = i;
    fclose(fp);

    /* input a key */
    printf("passwd: ");
    for (i = 0; (c = getchar()) != '\n'; i++)
        key[i] = c;
    key[i] = '\0';
    keylength = i;

    /* use key to generate a keystream */
    produceKeystream(textlength, key, keylength, keystream);

    /* use the keystream and plaintext to generate ciphertext */
    encrypt(textlength, plaintext, keystream, ciphertext);

    fp = fopen(*argv, "w");
    for (int i = 0; i<textlength; i++)
        putc(ciphertext[i], fp);
    fclose(fp);
    return 0;
}

使用:cmd: 文件路径 文件名

上一篇: 快速幂取模

下一篇: rc4算法