常见加解密算法02 - RC4算法分析

news2025/1/21 22:07:05

RC4是一种广泛使用的流密码,它以其简洁和速度而闻名。区别于块密码,流密码特点在于按位或按字节来进行加密。

RC4由Ron Rivest在1987年设计,尽管它的命名看起来是第四版,实际上它是第一个对外发布的版本。

RC4算法的实施过程简洁明了,主要包括初始化和生成密钥流这两个阶段。

下面我们就一边解析算法,一边分析其代码实现。

初始化

该阶段的核心任务是利用一个可变长度的密钥来初始化一张S盒,即一个包含0至255所有字节的256长度数组。初始化步骤如下:

  • 初始填充S盒,按顺序排列0至255的数值。

  • 使用密钥对S盒进行置换。每个S盒中的元素都会根据密钥中的字节进行一定的交换。这个过程叫做密钥调度算法(KSA)。

说的形象一点就是:在桌子上有256个小盒子(从0到255编号),初始时每个盒子里面的数字和它的编号一样。现在,你开始根据密钥来交换这些盒子里面的数字,直到所有的盒子都被重新排列。

经过多轮置换,这256个数字的顺序就变得无规律。将此与洗牌对比,虽然结果看似随机,实则完全受密钥控制。

现在,我们来看一下代码实现:

private static void initAndPermute(char[] byteKey) {
    if (byteKey.length > 256 || byteKey.length < 1) {
        System.out.println("Key length must be between 1 to 256 chars");
    } else {
        // Creation of initial state and key bytes
        keylength = byteKey.length;
        for (int i = 0; i < 256; i++) {
            S[i] = i;
            K[i] = byteKey[i % keylength];
        }
        // Permuting state bytes based on values of key bytes
        int j = 0;
        for (int i = 0; i < 256; i++) {
            j = (j + S[i] + K[i]) % 256;
            int temp = S[i];
            S[i] = S[j];
            S[j] = temp;
        }
    }
}

第一个 for 循环里面,就是初始化 S 盒。我们还看到同时也给 K 数组赋值了,这里说明了一个问题,K 的长度大于 256 之后,后面的其实没用,所以我们的密钥不用写太长,除非写一个变种算法。

看第二个循环,j = (j + S[i] + K[i]) % 256; 我们把它看成一个数学表达式 j = f(i),这个表达式最终会生成一个 0-255 之间的一个数字 j,然后将 i 与 j 位置进行交换,这样就扰乱了 S 盒的数字顺序。

操作 (PRGA)

在操作阶段,RC4生成伪随机流,称为密钥流。这个密钥流会与明文按位异或来生成密文。同样,将密钥流与密文按位异或,可以得到原始明文。操作过程如下:

  • 初始化两个指针i和j(都开始于0)。

  • 在每次操作中,i递增1,j加上S盒在i位置的值,并使用新的j值来更新S盒中的元素位置。

  • 选取i和j指向的两个元素,将它们加起来,并根据这个总和得到S盒中的某个元素作为密钥流的一部分。

  • 重复此过程,直到生成了足够长的密钥流,可以与明文进行异或操作。

上面的步骤比较难以理解,但是我们利用数学的思想来看:

首先,定义两个变量 i 与 j,然后给它们赋值,i = f(i), j = f(i, j) ,然后再定义一个变量 key,key = f2(i, j) 。这个key就是根据 S 盒生成的密钥流,只要 S 的顺序固定,那么生成的密钥流就是固定的。有了密钥流,那么我们就可以与明文做异或操作。

看代码:

private static char[] encryptRC4(char[] plainText) {
    char[] cipherText = new char[plainText.length];
    int i = 0;
    int j = 0;
    int key;
    int plainTextLen = 0;
    while (plainTextLen < plainText.length) {
        // Key generation
        i = (i + 1) % 256;
        j = (j + S[i]) % 256;
        int temp = S[i];
        S[i] = S[j];
        S[j] = temp;
        key = S[(S[i] + S[j]) % 256];
        // Encryption
        cipherText[plainTextLen] = (char) (plainText[plainTextLen] ^ key);
        plainTextLen++;
    }
    return cipherText;
}

有的小伙伴可能想得多一点,既然是使用异或做操作,那么加密算法其实就是解密算法!

是的,异或这个东西很神奇, x ^ y ^ y 还是 x。既然加密算法保证了 S 一定的情况下,生成的 key 是一样的,所以解密算法可以直接使用加密算法。

C 实现

#define N 256   // 2^8

void swap(unsigned char *a, unsigned char *b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

int KSA(char *key, unsigned char *S) {

    int len = strlen(key);
    int j = 0;

    for(int i = 0; i < N; i++)
        S[i] = i;

    for(int i = 0; i < N; i++) {
        j = (j + S[i] + key[i % len]) % N;

        swap(&S[i], &S[j]);
    }

    return 0;
}

int PRGA(unsigned char *S, char *plaintext, unsigned char *ciphertext) {

    int i = 0;
    int j = 0;

    for(size_t n = 0, len = strlen(plaintext); n < len; n++) {
        i = (i + 1) % N;
        j = (j + S[i]) % N;

        swap(&S[i], &S[j]);
        int rnd = S[(S[i] + S[j]) % N];

        ciphertext[n] = rnd ^ plaintext[n];

    }

    return 0;
}

int RC4(char *key, char *plaintext, unsigned char *ciphertext) {

    unsigned char S[N];
    KSA(key, S);

    PRGA(S, plaintext, ciphertext);

    return 0;
}

总结

RC4的好处是它很简单,很快,在没有密钥的情况下只能使用暴力破解。所以,你的密钥很重要,你得特别小心使用它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1673763.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动态el-form表单以及动态禁用

当右侧下拉框选中为 长期有效,那么左侧输入框为禁用状态; <el-form-item label"证明有效期" class"is-required"><div v-for"(item,index) in form.arrayDat" :key"index" style"width: 100%;display: flex;justify-co…

深度解读《深度探索C++对象模型》之虚继承的实现分析和效率评测(二)

目录 通过子类的指针存取虚基类成员的实现分析 通过第一基类的指针存取虚基类成员的实现分析 通过第二基类的指针存取虚基类成员的实现分析 通过虚基类的指针存取虚基类成员的实现分析 小结 存取虚基类成员与普通类成员的效率对比 接下来我将持续更新“深度解读《深度探索…

WS2812B-2020 智能控制LED集成光源芯片IC

一般说明 WS2812B-2020是一款智能控制LED光源&#xff0c;它的外部采用了最新的模压封装技术&#xff0c;控制电路和RGB芯片集成在一个2020组件中。其内部包括智能数字端口数据锁存器和信号整形放大驱动电路。还包括一个精密的内部振荡器和一个电压可编程恒流控制部分&…

对关系型数据库管理系统的介绍

1.数据库的相关介绍 关系型数据库管理系统&#xff1a;&#xff08;英文简称&#xff1a;RDBMS&#xff09; 为我们提供了一种存储数据的特定格式&#xff0c;所谓的数据格式就是表&#xff0c; 在数据库中一张表就称为是一种关系. 在关系型数据库中表由两部分组成&#xf…

嵌入式和单片机的区别在哪?

嵌入式和单片机是两个不同的概念&#xff0c;它们在很多方面都存在着差异。嵌入式系统是一种专用的计算机系统&#xff0c;通常用于控制和监测其他设备。它通常由微处理器、存储器、输入/输出接口和其他外围设备组成。嵌入式系统可以运行各种操作系统&#xff0c;如 Linux、Win…

TCP/UDP通信中的部分函数

UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;和TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是互联网协议套件中最常用的两种传输层协议&#xff0c;它们负责在互联网中端到端地传输数据。尽管它们服务…

web网页录音(recorder.js)并上传后端语音转文字(Vosk)

我是一个后端开发人员&#xff0c;现在都快进化成全栈了。操了&#xff0c;是谁有好的项目让我跳跳槽&#xff0c;转转行吧 写在前面&#xff0c;很重要 这是官方文档的说明 翻译如下&#xff1a; 我们有两种型号-大型号和小型号&#xff0c;小型号非常适合在移动应用程序上执…

IT行业现状与未来趋势分析

IT行业现状与未来趋势显示出持续的活力和变革&#xff0c;以下是上大学网&#xff08;www.sdaxue.com&#xff09;关于IT行业现状与未来趋势分析&#xff0c;供大家参考。 当前现状&#xff1a; 市场需求持续增长&#xff1a;随着信息时代的深入发展&#xff0c;各行各业对信息…

一条查询SQL的执行过程

1.1 假设 查询语句为&#xff1a;mysql> select * from T where ID 10 1.2 总体执行流程 1.2.1 连接器 -> 连接 作用&#xff1a;负责跟客户端建立连接、获取权限、维持和管理连接等工作流程&#xff1a; 一个用户成功建立连接后&#xff0c;如果客户端太长时间没有请…

跨ROS系统通信:使用TCP实现节点间的直连

当涉及到在机器人操作系统&#xff08;ROS&#xff09;环境中的通信时&#xff0c;标准做法通常是在同一个ROS网络内通过话题和服务进行。但在某些特定情况下&#xff0c;比如当你有两个分布在不同网络中的ROS系统时&#xff0c;标准的通信方法可能不太适用。此时&#xff0c;一…

SpringBoot集成Seata分布式事务OpenFeign远程调用

Docker Desktop 安装Seata Server seata 本质上是一个服务&#xff0c;用docker安装更方便&#xff0c;配置默认&#xff1a;file docker run -d --name seata-server -p 8091:8091 -p 7091:7091 seataio/seata-server:2.0.0与SpringBoot集成 表结构 项目目录 dynamic和dyna…

EmotiVoice 实时语音合成TTS;api接口远程调用

参考:https://github.com/netease-youdao/EmotiVoice 测试整体速度可以 docker安装: 运行容器:默认运行了两个服务,8501 一个streamlit页面,另外8000是一个api接口服务 docker run -dp 8501:8501 -p 8250:8000 syq163/emoti-voice:latest##gpu运行 (gpu运行遇到CUDA er…

山东齐鲁文化名人颜廷利:朱郭有文才,曲高‘菏’寡星光路

山东齐鲁文化名人颜廷利教授表示&#xff0c;朱郭&#xff08;谐音‘祖国’&#xff09;有文才&#xff0c;《曲高‘菏’寡》星光路… 山东菏泽歌手朱之文在2011年凭借一首《滚滚长江东逝水》一夜成名&#xff0c; 十多年之后的今天&#xff0c;菏泽市网络红人郭有才靠一首《诺…

LeetCode---循环队列

循环队列就是只有固定的内存&#xff0c;存数据&#xff0c;出数据&#xff0c;但是也和队列一样&#xff0c;先进先出。如下图所示&#xff0c;这是他的样子 在head出&#xff0c;tail进&#xff0c;但是这个如果用数组解决的话&#xff0c;就有问题&#xff0c;力扣给我们的接…

Django模型进阶-多对多关系

在Django中&#xff0c;多对多&#xff08;Many-to-Many&#xff09;关系是一种数据库关系&#xff0c;表示一个模型的实例可以与另一个模型的多个实例相关联&#xff0c;同时另一个模型的实例也可以与这个模型的多个实例相关联。换句话说&#xff0c;就是两个模型之间可以存在…

免费SSL证书获取与部署教程

在互联网时代&#xff0c;HTTPS已成为网站安全的基石&#xff0c;为用户数据传输提供加密保障。免费SSL证书的出现降低了部署HTTPS的门槛&#xff0c;尤其对于个人网站、小微企业及测试环境而言&#xff0c;它们是理想的选择。本文旨在提供一份详尽指南&#xff0c;帮助您轻松获…

找到字符串中所有的字母异位词 ---- 滑动窗口

题目链接 题目: 分析: 要找的是在s中和p是异位词的子串, 也就是说子串大小和p相同, 那么就是窗口大小固定的滑动窗口问题可以使用哈希数组来记录每个元素出现的个数, 定义hash1存放p中的各元素个数定义left 0; right 0;进窗口 让right指向的元素进窗口, 即更新hash2中的元素…

基于若依的ruoyi-nbcio流程管理系统支持指定接收人的流程审批

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

【SRC实战】无限获取优惠码

挖个洞先 https://mp.weixin.qq.com/s/HgMK4S8275VvFVbnSp6Qsw “ 以下漏洞均为实验靶场&#xff0c;如有雷同&#xff0c;纯属巧合 ” 01 — 漏洞证明 “ 获取优惠码有次数限制的情况下&#xff0c;如何绕过&#xff1f;” 1、新用户专属福利&#xff0c;免费领100元优惠…

Can not add resource (com.android.aaptcompiler.ParsedResource@a980fbb) to table

具体原因 资源合并时出现编译问题。 1. 什么是资源&#xff1f; 就是res目录下面的values目录下的文件。以及&#xff01;以及&#xff01;你所引入的其他依赖&#xff08;第三方库&#xff09;的values.xml文件 2. 一般什么原因会导致合并出错? 你的资源文件中的内容错误&…