对称加密算法之RC4介绍及OpenSSL中RC4常用函数使用举例

2023-05-16

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的所有元素都被赋值。这些预操作可概括如下:

/*初始化*/
for i = 0 to 255 do
	S[i]= i;
	T[i]= K[i mod keylen];

然后用T产生S的初始置换,从S[0]到S[255],对每个S[i],根据由T[i]确定的方案,将S[i]置换为S中的另一字节:

/*S的初始序列*/
j= 0
for i = 0 to 255 do
	j= (j + S[i] + T[i]) mod 256
	swap(S[i],S[j]);

因为对S的操作仅是交换,所以惟一的改变就是顺序的改变。S仍然包含从0到255的所有元素,在初始化的过程中,密钥的主要功能是将S-box搅乱,代码中的变量i确保S-box的每个元素都得到处理,变量j保证S-box的搅乱是随机的。因此不同的S-box在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列,并且该序列是随机的。

伪随机序列生成算法:矢量S一旦完成初始化,输入密钥就不再被使用。密钥流的生成是从S[0]到S[255],对每个S[i],根据当前S的值,将S[i]与S中的另一字节置换。当S[255]完成置换后,操作继续重复,从S[0]开始:

/*密钥流的产生*/
i,j = 0;
while(true)
	i= (i + 1) mod 256;
	j= (j + S[i]) mod 256;
	swap(S[i],S[j]);
	t= (S[i] + s[j]) mod 256;
	k= S[t]

伪随机序列一旦生成,就得到子密码sub_k,把子密钥和明文进行异或运算,得到密文。解密过程也完全相同。加密中,只需将k的值与下一明文字节异或;相反解密中,将k的值与下一密文字节异或就可以还原出明文信息。算法描述为:

for(i = 0; i < textlength; i ++)
	ciphertext[i]= keystream[i] ^ plaintext[i]

RC4算法存在的问题:因为RC4算法具有实现简单,加密速度快,对硬件资源耗费低等优点,使其跻身于轻量级加密算法的行列。但是其简单的算法结构也容易遭到破解攻击,RC4算法的加密强度完全取决于密钥,即伪随机序列生成,而真正的随机序列是不可能实现,只能实现伪随机。这就不可避免出现密钥的重复。RC4算法不管是加密还是解密,都只进行了异或运算,这就意味着,一旦子密钥序列出现了重复,密文就极有可能被破解。

具体破解过程如下:若明文、密钥是任意长的字节,可以用重合码计数法(counting coincidence)找出密钥长度。把密文进行各种字节的位移,并与原密文进行异或运算,统计那些相同的字节。如果位移是密钥长度的倍数,那么超过60%的字节将是相同的;如果不是,则至多只有0.4%的字节是相同的,这叫做重合指数(index of coincidence)。找出密钥长度倍数的最小位移,按此长度移到密文,并且和自身异或。由于明文每字节有1.3位的实际信息,因此有足够的冗余度去确定位移的解密。对所有的密钥,输出密钥流的前几个字节不是随机的,因此极有可能会泄露密钥的信息。如果一个长期使用的密钥与一个随机数串联产生RC4算法密钥,那么可以通过分析大量由该密钥加密的密文得到这个长期使用的密钥。解决该问题的办法是:抛弃密钥流最初的那部分数据。

RC4is a stream cipher with variable key length. Typically, 128 bit (16 byte) keys are used for strong encryption, butshorter insecure key sizes have been widely used due to export restrictions.

1. RC4_set_key:sets up theB<RC4_KEY> B<key> using the B<len> bytes long key atB<data>.

2. RC4: encrypts or decrypts the B<len>bytes of data at B<indata> using B<key> and places the result atB<outdata>.  Repeated RC4() callswith the same B<key> yield a continuous key stream. Since RC4 is a streamcipher (the input is XORed with a pseudo-random key stream to produce theoutput), decryption uses the same function calls as encryption.

以下是测试代码:

namespace {
void RC4_Encrypt(const unsigned char* cleartext, int length, const std::string& key, unsigned char* ciphertext)
{
	RC4_KEY rc4key;

	RC4_set_key(&rc4key, key.length(), (const unsigned char*)key.c_str());
	RC4(&rc4key, length, cleartext, ciphertext);
}

void RC4_Decrypt(const unsigned char* ciphertext, int length, const std::string& key, unsigned char* cleartext)
{
	RC4_KEY rc4key;

	RC4_set_key(&rc4key, key.length(), (const unsigned char*)key.c_str());
	RC4(&rc4key, length, ciphertext, cleartext);
}

} // namespace

int test_openssl_rc4()
{
	const std::string cleartext = "中国北京12345$abcde%ABCDE@!!!!";
	const std::string key = "beijingchina1234567890ABCDEFGH!!!";

	char* cleartext_encode = b64_encode((const unsigned char*)cleartext.c_str(), cleartext.length());
	int length = strlen(cleartext_encode);
	fprintf(stdout, "cleartext encode length: %d\n", length);

	std::unique_ptr<unsigned char[]> ciphertext(new unsigned char[length]);
	RC4_Encrypt((const unsigned char*)cleartext_encode, length, key, ciphertext.get());

	std::unique_ptr<unsigned char[]> decrypt(new unsigned char[length]);
	RC4_Decrypt(ciphertext.get(), length, key, decrypt.get());

	unsigned char* ciphertext_decode = b64_decode((char*)decrypt.get(), length);

	fprintf(stdout, "src cleartext: %s\n", cleartext.c_str());
	fprintf(stdout, "genarate ciphertext: %s\n", ciphertext.get());
	fprintf(stdout, "dst cleartext: %s\n", ciphertext_decode);
	int ret = 0;

	if (strcmp(cleartext.c_str(), (const char*)ciphertext_decode) == 0) {
		fprintf(stdout, "RC4 decrypt success\n");
	} else {
		fprintf(stderr, "RC4 decrypt fail\n");
		ret = -1;
	}

	free(cleartext_encode);
	free(ciphertext_decode);
	return ret;
}

执行结果如下:

RC4理论摘自:《RFID中轻量级加密算法及实现技术的研究》

GitHub:https://github.com/fengbingchun/OpenSSL_Test

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对称加密算法之RC4介绍及OpenSSL中RC4常用函数使用举例 的相关文章

  • IAR 中如何调用EmEditor

    IAR 中如何调用EmEditor 文本编辑器我一直都用EmEditor Emeditor是一款很优秀的纯文本编辑器 xff0c 它对中日韩等亚洲字符集支持的很好 xff0c 不仅有语法高亮显示功能 xff0c 搜索替换功能也是近乎可爱的强
  • 花了一下午,弄明白四个名词 USCI,USI,LIN,IrDa

    最近在看MSP的程序 xff0c TI的官方例子程序 xff0c 有些名词看了却不知道什么意思 xff0c 本着穷根问底的态度 xff0c 上网搜索 xff0c 花了一下午 xff0c 弄明白四个名词 USCI xff0c USI xff0
  • Cadence 17.2学习笔记--显示元件丝印及元件标号的设置

    快捷键Ctrl 43 F5 调出Color Dialog 左侧菜单第三项Geometry选项 钩选图中Silkscreen Top或Silkscreen Bottom可打开或关闭元件外形丝印的显示 同样Color Dialog对话框 左侧菜
  • 【Android UI】色板

    Hex CodeColor FFFFFF FFFFCC FFFF99 FFFF66 FFFF33 FFFF00 FFCCFF FFCCCC FFCC99 FFCC66 FFCC33 FFCC00 FF99FF FF99CC FF9999 F
  • 对称加密算法AES简介及在OpenSSL中使用举例

    高级加密标准 AES Advanced Encryption Standard 由美国国家标准和技术协会 NIST 于2000年公布 xff0c 它是一种对称加密算法 xff0c 用来替代DES AES也称为Rijndael算法 xff0c
  • 基于Hash的消息认证码HMAC简介及在OpenSSL中使用举例

    HMAC Hash based Message Authentication Code xff1a 基于Hash的消息认证码 xff0c 是一种通过特别计算方式之后产生的消息认证码 MAC xff0c 使用密码散列函数 xff0c 同时结合
  • 在Windows和Linux上编译gRPC源码操作步骤(C++)

    gRPC最新发布版本为v1 23 0 xff0c 下面以此版本为例说明在Windows和Linux下编译过程 Windows7 10 vs2103编译gRPC源码操作步骤 xff1a 1 需要本机已安装Git CMake Perl Go y
  • gRPC简介及简单使用(C++)

    gRPC是一个现代的 开源的 高性能远程过程调用 RPC 框架 xff0c 可以在任何平台运行 gRPC使客户端和服务器端应用程序能够透明地进行通信 xff0c 并简化了连接系统的构建 gRPC支持的语言包括C 43 43 Ruby Pyt
  • C语言中select函数简介及使用

    select函数用来检查套接字描述符 sockets descriptors 是否已准备好读 写 xff0c 提供了一种同时检查多个套接字的方法 Linux中select函数的声明在 usr include x86 64 linux gnu
  • VS Code离线安装C/C++插件cpptools-linux-aarch64.vsix

    一 问题 最近VS Code连接jetson nano xff0c 经常提示加载C C 43 43 插件失败 二 解决方法 根据提示 xff0c 在githup上 https github com microsoft vscode cppt
  • 开源库BearSSL介绍及使用

    BearSSL是用C语言实现的SSL TLS协议 xff0c 它的源码可直接通过git clone https www bearssl org git BearSSL 下载 xff0c 它的license是MIT xff0c 最新版本为0
  • 对称加密算法AES之GCM模式简介及在OpenSSL中使用举例

    AES Advanced Encryption Standard 即高级加密标准 xff0c 由美国国家标准和技术协会 NIST 于2000年公布 xff0c 它是一种对称加密算法 关于AES的更多介绍可以参考 xff1a https bl
  • ASN.1简介及OpenSSL中ASN.1接口使用举例

    ASN 1 Abstract Syntax Notation One 是一套标准 xff0c 是描述数据的表示 编码传输 解码的灵活的记法 它提供了一套正式 无歧义和精确的规则以描述独立于特定计算机硬件的对象结构 OpenSSL的编码方法就
  • 从openssl rsa pem文件中提取公私钥数据实现

    RSA为非对称加密算法 xff0c 关于其介绍可以参考 xff1a https blog csdn net fengbingchun article details 43638013 OpenSSL最新版为 1 1 1g xff0c 在Wi
  • 通过OpenSSL的接口实现Base64编解码

    对openssl genrsa产生的rsa私钥pem文件 xff0c 使用普通的base64解码会有问题 xff0c 如使用https blog csdn net fengbingchun article details 85218653
  • JWT(JSON Web Token)简介及实现

    JWT JSON Web Token xff1a 是一个开放标准 RFC 7519 xff0c 它定义了一种紧凑且自包含的方式 xff0c 用于在各方之间作为Json对象安全地传输信息 由于此信息是经过数字签名的 xff0c 因此可以被验证
  • SSL/TLS单向认证和双向认证介绍

    为了便于理解SSL TLS的单向认证和双向认证执行流程 xff0c 这里先介绍一些术语 1 散列函数 Hash function xff1a 又称散列算法 哈希函数 xff0c 是一种从任何一种数据中创建小的数字 指纹 的方法 散列函数把消
  • 使用OpenSSL生成自签名证书相关命令

    在用于小范围测试等目的的时候 xff0c 用户也可以自己生成数字证书 xff0c 但没有任何可信赖的机构签名 xff0c 此类数字证书称为自签名证书 证书一般采用X 509标准格式 下面通过OpenSSL相关命令介绍如何生成自签证书 1 生
  • Windows/Linux TCP Socket网络编程简介及测试代码

    典型的网络应用是由一对程序 即客户程序和服务器程序 组成的 xff0c 它们位于两个不同的端系统中 当运行这两个程序时 xff0c 创建了一个客户进程和一个服务器进程 xff0c 同时它们通过从套接字 socket 读出和写入数据在彼此之间
  • 基于BearSSL实现自签名证书双向认证测试代码

    客户端 服务器端双向认证大致过程 xff1a 可以参考 xff1a https blog csdn net fengbingchun article details 106856332 1 客户端发起连接请求 xff1b 2 服务器端返回消

随机推荐

  • C:\KEIL\C51\intrins.h包含不正确的路径。Keil 头文件路径错误

    步骤1 xff1a 先检查工程中的 include intrins h include stdio h xff0c 各文件之间 是否正确调用 步骤2 xff1a 将 include lt intrins h gt lt reg52 h gt
  • 分享一个Centos8的国内yum源

    使用的是阿里巴巴开源镜像站 xff0c 文件地址 xff1a https span class token punctuation span span class token operator span span class token o
  • 网络数据包分析软件Wireshark简介

    Wireshark是被广泛使用的免费开源的网络协议分析软件 network protocol analyzer 或网络数据包分析软件 xff0c 它可以让你在微观层面上查看网络上发生的事情 xff0c 它的功能是截取网络数据包 xff0c
  • HTTP请求方法介绍

    之前在https blog csdn net fengbingchun article details 85039308 中介绍过HTTP协议 xff0c 在https blog csdn net fengbingchun article
  • TCP Flags标志位介绍

    传输控制协议 Transmission Control Protocol xff0c TCP 是一种传输层协议 TCP使数据包从源到目的地的传输更加顺畅 它是一种面向连接的端到端协议 每个数据包由TCP包裹在一个报头中 xff0c 该报头由
  • 代理服务器简介及libcurl测试

    代理服务器英文全称是Proxy Server xff0c 其功能就是将局域网用户连接到Internet xff0c 代理网络用户去获得网络信息 形象地说 xff0c 它是网络信息的中转站 xff0c 是连接内部局域网和Internet的一种
  • CMake中find_package的使用

    CMake中的命令find package用于查找指定的package find package支持两种主要的搜索方法 xff1a 注意 xff1a lt PackageName gt 是区分大小写的 1 Config mode 配置模式
  • CMake中link_directories/target_link_directories的使用

    CMake中的link directories命令用于添加目录使链接器能在其查找库 add directories in which the linker will look for libraries xff0c 其格式如下 xff1a
  • UDP协议在Windows上使用示例

    UDP User Datagram Protocol xff0c 用户数据报协议 是无连接的 xff0c 因此在两个进程通信前没有握手过程 UDP协议提供一种不可靠数据传送服务 xff0c 也就是说 xff0c 当进程将一个报文发送进UDP
  • 代码覆盖率工具OpenCppCoverage在Windows上的使用

    OpenCppCoverage是用在Windows C 43 43 上的开源的代码覆盖率工具 xff0c 源码地址为https github com OpenCppCoverage OpenCppCoverage xff0c 最新发布版本为
  • nerfstudio介绍及在windows上的配置、使用

    nerfstudio提供了一个简单的API xff0c 可以简化创建 训练和可视化NeRF的端到端过程 该库通过模块化每个组件来支持可解释的NeRF实现 nerfstudio源码地址 https github com nerfstudio
  • Qt中QDebug的使用

    QDebug类为调试信息 debugging information 提供输出流 它的声明在 lt QDebug gt 中 xff0c 实现在Core模块中 将调试或跟踪信息 debugging or tracing information
  • OkHttpUtil

    package com example someutil util import com google gson Gson import java util Iterator import java util Map import java
  • Sourcetree介绍及使用

    Sourcetree是一个操作简单但功能强大的免费Git客户端管理工具 xff0c 可应用在Windows和Mac平台 Sourcetree的安装 xff1a 1 从Sourcetree Free Git GUI for Mac and W
  • C++14中lambda表达式新增加的features的使用

    lambda表达式是在C 43 43 11中引入的 xff0c 它们可以嵌套在其它函数甚至函数调用语句中 xff0c C 43 43 11中lambda表达式的使用参考 xff1a https blog csdn net fengbingc
  • OpenSSL简介及在Windows、Linux、Mac系统上的编译步骤

    OpenSSL介绍 xff1a OpenSSL是一个强大的安全套接字层密码库 xff0c 囊括主要的密码算法 常用的密钥和证书封装管理功能及SSL协议 xff0c 并提供丰富的应用程序供测试或其它目的使用 SSL是SecureSockets
  • 信息安全领域相关术语介绍

    一 SSL 安全套接字层 SSL Secure Sockets Layer 是一种协议 xff0c 支持服务通过网络进行通信而不损害安全性 它在客户端和服务器之间创建一个安全连接 然后通过该连接安全地发送任意数据量 SSL最初是用来保障数据
  • 对称加密算法之DES介绍

    DES Data Encryption Standard 是分组对称密码算法 DES采用了64位的分组长度和56位的密钥长度 xff0c 它将64位的输入经过一系列变换得到64位的输出 解密则使用了相同的步骤和相同的密钥 DES的密钥长度为
  • OpenSSL中对称加密算法DES常用函数使用举例

    主要包括3个文件 xff1a 1 cryptotest h ifndef CRYPTOTEST H define CRYPTOTEST H include lt string gt using namespace std typedef e
  • 对称加密算法之RC4介绍及OpenSSL中RC4常用函数使用举例

    RC4是一种对称密码算法 xff0c 它属于对称密码算法中的序列密码 streamcipher 也称为流密码 xff0c 它是可变密钥长度 xff0c 面向字节操作的流密码 RC4是流密码streamcipher中的一种 xff0c 为序列