V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
raiz
V2EX  ›  Python

python Crypto.Cipher.AES 每次加密的结果是不确定的?

  •  
  •   raiz · 2015-10-04 22:21:08 +08:00 · 5549 次点击
    这是一个创建于 3337 天前的主题,其中的信息可能已经有所发展或是发生改变。
    def aesEncrypt(text, secKey):
        pad = 16 - len(text) % 16
        text = text + pad * b' '  #  chr(pad)
        encryptor = AES.new(secKey, 2, '0102030405060708')   
        ciphertext = encryptor.encrypt(text)  # 加密 text
        print(ciphertext)  
        ciphertext = base64.b64encode(ciphertext)  #
        # return bytes.decode(ciphertext)
        return ciphertext
    

    发现相同的 text , secKey 参数,多次运行 aesEncrypt(), print(ciphertext) 的结果不一样, 这不会是 aes 的特性吧??

    第 1 条附言  ·  2015-10-04 23:49:12 +08:00
    搞明白了, 加密的结果是确定的。
    14 条回复    2015-10-06 10:22:33 +08:00
    xupefei
        1
    xupefei  
       2015-10-04 22:25:39 +08:00
    除了你说的那些参数以外,还有个 initialization vector ,就是常说的 iv 。这个 iv 一半是加密时随即产生的。 iv 不同,加密结果不同。
    xupefei
        2
    xupefei  
       2015-10-04 22:29:03 +08:00
    @xupefei *一般是加密时随机产生的。
    pynix
        3
    pynix  
       2015-10-04 22:36:27 +08:00 via Android
    这大概是 GFW 拿 ase256 没办法的原因
    neilp
        4
    neilp  
       2015-10-04 22:52:58 +08:00 via iPhone
    py 的 aes 没用过,所以代码没细看。 但是就 aes 算法本身来讲,同一个文本加密的密文一定是一样的。 除非你的 iv 设置的不一样.
    如果加密的文本大于一个块, 那么加密得到的密文 还取决于 不同块之间 iv 的 重复利用方式。 也就是所谓的 cipher mode. 即使所谓的 ecb , cbc, cfb 。 以 cbc 为例,加密第一块时, iv 由用户指定,如果用户没指定, 多数平台的 aes 实现会用全零的块作为默认 iv. 在加密第二块时会用第一块加密出来的密文作为新的 iv. 并以此类推。

    楼主的情况应该不涉及多块的问题, 所以找找看有没有设置 iv 的接口, 给个固定的 iv 试试。

    火车上用手机发的帖子,请海涵
    raiz
        5
    raiz  
    OP
       2015-10-04 23:01:34 +08:00
    @xupefei 意思是说 '0102030405060708' 只是 iv 的一半,另一半具有随机性??
    > def new(key, *args, **kwargs):
    """Create a new AES cipher

    :Parameters:
    key : byte string
    The secret key to use in the symmetric cipher.
    It must be 16 (*AES-128*), 24 (*AES-192*), or 32 (*AES-256*) bytes long.
    :Keywords:
    mode : a *MODE_** constant
    The chaining mode to use for encryption or decryption.
    Default is `MODE_ECB`.
    IV : byte string
    The initialization vector to use for encryption or decryption.
    """

    不过,以上的实验室 python3.4 下的, 我又在 python27 底下做相同的实验,发现结果是不变的
    xupefei
        6
    xupefei  
       2015-10-04 23:07:55 +08:00
    @raiz
    Parameters:
    mode (a MODE_* constant) - The chaining mode to use for encryption or decryption. *Default is MODE_ECB.*
    IV (byte string) - The initialization vector to use for encryption or decryption.
    *It is ignored for MODE_ECB and MODE_CTR.*
    raiz
        7
    raiz  
    OP
       2015-10-04 23:08:48 +08:00
    @neilp 谢谢。 AES.new() 的 doc string 显示 AES.new(secKey, 2, '0102030405060708')第三个参数 就是 iv, 所以我认为应该是确定的结果才对, python2.7 下做的实验输出是确定的,前面的实验是 python3.4 下做的,结果是几种可能性中随机的一种,很怪
    xupefei
        8
    xupefei  
       2015-10-04 23:09:50 +08:00
    @xupefei 啊,没注意原来 LZ 制定了 MODE_CBC 模式。请无视上面的回复。
    我没看过 py 实现的源码,无法给出答案了。
    raiz
        9
    raiz  
    OP
       2015-10-04 23:11:07 +08:00
    @xupefei MODE_CBC = 2 ,所以这里是 CBC 模式, IV 没有忽略
    fengdra
        10
    fengdra  
       2015-10-04 23:41:27 +08:00
    我这每次执行都是一样的,你是不是同一个 encryptor 用了多次?密文还依赖于这个 encryptor 的历史
    raiz
        11
    raiz  
    OP
       2015-10-04 23:48:08 +08:00
    @fengdra 哦哦哦 我知道问题出在哪了 是我的输入是 json.dump() 一个字典,字典的排序是随机的,所以会变。 关注点一直没移开加密过程,没去看输入。 谢谢你
    twor2
        12
    twor2  
       2015-10-05 01:49:42 +08:00   ❤️ 1
    Pasco
        13
    Pasco  
       2015-10-05 18:43:09 +08:00 via iPhone
    是这样的,解密的结果是对的不就好了~
    raiz
        14
    raiz  
    OP
       2015-10-06 10:22:33 +08:00
    @Pasco 是这样,我那时是在调试一个 api , 原来是 python27 的代码,改为 python3 之后响应不对,所以特意设置相同的输入,观察输出的区别,后来发现是 编码转换的用法不同导致。而之所以 python27 每次输出固定是因为 dict 的顺序总是固定的,而 python34 是随机的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1123 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:34 · PVG 02:34 · LAX 10:34 · JFK 13:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.