用 Python 进行 RC4 加解密


=Start=

缘由:

简单整理一下 RC4 加解密算法的相关知识,方便后面有需要的时候参考。

正文:

参考解答:
pip install pycryptodome

RC4 密码的介绍

在密码学中,RC4(也被称为ARC4或ARCFOUR)是一种流式密码算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS所采用的算法之一。

RC4是由美国密码学家罗纳德·李维斯特(Ronald Rivest)在1987年设计的。

RC4开始时是商业机密,没有公开发表出来,但是在1994年9月份的时候,它被人匿名公开在了 Cypherpunks 邮件列表上,很快它就被发到了 sci.crypt 新闻组上,随后从这传播到了互联网的许多站点。随之贴出的代码后来被证明是真实的,因为它的输出跟取得了RC4版权的私有软件的输出是完全相同的。由于算法已经公开,RC4也就不再是商业秘密了,只是它的名字“RC4”仍然是一个注册商标。RC4经常被称作是“ARCFOUR”或者”ARC4″(意思是称为RC4),这样来避免商标使用的问题。RSA Security从来没有正式公布这个算法,罗纳德·李维斯特在2008年的自己的课程笔记中给出了一个指向RC4的英文维基百科文章的链接,并且在2014年的文件中确认了RC4及其代码的历史。

RC4已经成为一些协议和标准的一部分,如1997年的WEP和2003年的WPA;和1995年的SSL,以及1999年的TLS。2015年2月由 RFC 7465 规定禁止RC4在所有版本的TLS中使用。

RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。

由于异或运算的对合性,RC4加密解密使用同一套算法。

ARC4(Alleged RC4)是 RC4(Rivest’s Cipher version 4)的实现。

ARC4 密钥的长度从 8 位到 2048 位不等。

用 Python 进行 RC4 加解密的样例代码

import base64
from Crypto.Cipher import ARC4 as rc4cipher

def rc4_str(encrypt_or_decrypt, msg, key):
    if encrypt_or_decrypt == "encrypt":
        key = bytes(key, encoding='utf-8')
        enc = rc4cipher.new(key)
        res = enc.encrypt(msg.encode('utf-8')) # encrypt输入需要是 bytes 类型
        print('type({0}) of rc4 {1} return'.format(type(res), encrypt_or_decrypt))
        res = base64.b64encode(res) #base64编码,将内容编码为可见字符
        res = str(res,'utf8')
        return res
    elif encrypt_or_decrypt == "decrypt":
        msg = base64.b64decode(msg) #base64解码,还原内容以进行解密
        key = bytes(key, encoding='utf-8')
        enc = rc4cipher.new(key)
        res = enc.decrypt(msg) #decrypt输出也是 bytes 类型
        print('type({0}) of rc4 {1} return'.format(type(res), encrypt_or_decrypt))
        res = str(res,'utf8')
        return res

def encrypt_decrypt_rc4():
    msg = '测试string'
    key = 'password_here'
    enc1 = rc4_str('encrypt', msg, key)
    print(enc1)
    dec1 = rc4_str('decrypt', enc1, key)
    print(dec1)
#encrypt_decrypt_rc4
参考链接:

RC4
https://en.wikipedia.org/wiki/RC4

How to decrypt a file that encrypted with rc4 using Python?
https://stackoverflow.com/questions/29607753/how-to-decrypt-a-file-that-encrypted-with-rc4-using-python

ARC4
https://pycryptodome.readthedocs.io/en/latest/src/cipher/arc4.html

python实现rc4加密解密,base64输出
https://cloud.tencent.com/developer/article/1685707

RC4 doesn’t work correctly with openssl command?
https://stackoverflow.com/questions/9329631/rc4-doesnt-work-correctly-with-openssl-command

RC4 encryption java
https://stackoverflow.com/questions/12289717/rc4-encryption-java

PyCryptodome install
https://pycryptodome.readthedocs.io/en/latest/src/installation.html

A self-contained cryptographic library for Python
https://github.com/Legrandin/pycryptodome

=END=


《 “用 Python 进行 RC4 加解密” 》 有 2 条评论

  1. RC4 doesn’t work correctly with openssl command?
    https://stackoverflow.com/questions/9329631/rc4-doesnt-work-correctly-with-openssl-command
    `
    RC4 has variable-length keys, and OpenSSL’s enc utility forces you to pick a key size. These other implementations you’re testing against make no such restriction, so your keys don’t match.
    RC4有可变长度的密钥,OpenSSL的enc实用程序强制您选择一个密钥大小。您测试的其他实现没有这样的限制,因此您的密钥不匹配。

    The documentation for the enc utility describes the allowed key sizes for the cipher:

    rc4 128 bit RC4
    rc4-64 64 bit RC4
    rc4-40 40 bit RC4

    So RC4 works only on a 128-bit (16-byte) key. Also, the -k option means to derive a key from the given passphrase. It does this internally using the EVP_BytesToKey function, which implements a Key Derivation Function (KDF).

    Anyway, long story short, your RC4 implementations aren’t using the same key. Use the -p option to have OpenSSL print the actual key it is using:
    总之,长话短说,您的RC4实现没有使用相同的密钥。使用 -p 选项让OpenSSL打印它正在使用的实际密钥:

    $ echo -ne “test” | openssl rc4 -k test -nosalt -e -nopad -p
    key=098F6BCD4621D373CADE4E832627B4F6

    Further, since it’s expecting 16-byte keys, it’ll zero-pad shorter keys even if you specify a short key with the -K (uppercase K) option. You can use xxd to find the ascii hex values of “test” and -p again to see OpenSSL’s key:

    $ echo -ne “test” | xxd
    0000000: 7465 7374 test
    $ echo -ne “test” | openssl rc4 -K 74657374 -nosalt -e -nopad -p
    key=74657374000000000000000000000000

    So you must match key lengths and specify a hex-value key with the -K option and you’ll see the RC4 implementations are equivalent. E.g., here I use RC-40 to restrict the key length to 5 bytes and use the 5-byte key “tests”, or 74 65 73 74 73.

    $ echo -ne “test” | openssl rc4-40 -K 7465737473 -nosalt -e -nopad | xxd
    0000000: dd9b 5cb9

    You’ll find that your web implementation gets the same result when given the key “tests”.
    `

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注