资讯专栏INFORMATION COLUMN

python(3.x) 实现AES 加解密

harryhappy / 712人阅读

摘要:首先安装确认安装的是版本版本的是不一样的文件头部的声明为我们可以生成一个随机的密钥注意要使用密码学安全的随机方法这里生成的是而不是为了可读性采用加密内容加密前需要到的整数倍长度才可有对应方法初始向量为长度返回初始向量加密数据解密方法为

首先 安装cryptography

sudo pip3 install cryptography

确认安装的是2.1.x版本 (1.x版本的api是不一样的).

文件头部的声明为:

# coding: utf-8

import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
import base64

# 128bits block size
aes_block_size = 16

我们可以生成一个随机的密钥:

def get_random_key_readable(key_size=256):
    """
    get random key for symmetric encryption
    with key_size bits
    :param key_size: bit length of the key
    :return: bytes key
    """
    # length for urandom
    ulen = int(key_size/8/4*3)
    key = base64.b64encode(os.urandom(ulen))
    return key

注意要使用密码学安全的随机方法os.urandom.
这里生成的是str而不是bytes, 为了可读性.

采用AES CBC 加密:

def aes_cbc_encrypt(message, key):
    """
    use AES CBC to encrypt message, using key and init vector
    :param message: the message to encrypt
    :param key: the secret
    :return: bytes init_vector + encrypted_content
    """
    iv_len = 16
    assert type(message) in (str,bytes)
    assert type(key) in (str,bytes)
    if type(message) == str:
        message = bytes(message, "utf-8")
    if type(key) == str:
        key = bytes(key, "utf-8")
    backend = default_backend()
    iv = os.urandom(iv_len)
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
    encryptor = cipher.encryptor()
    padder = padding.PKCS7(128).padder()
    padded_data = padder.update(message) + padder.finalize()
    enc_content = encryptor.update(padded_data) + encryptor.finalize()
    return iv + enc_content

内容加密前需要padding到128bit(16bytes)的整数倍长度才可. cryptography有对应padding方法.
初始向量为16bit长度. 返回初始向量+加密数据.

解密方法为:

def aes_cbc_decrypt(content, key):
    """
    use AES CBC to decrypt message, using key
    :param content: the encrypted content using the above protocol
    :param key: the secret
    :return: decrypted bytes
    """
    assert type(content) == bytes
    assert type(key) in (bytes, str)
    if type(key) == str:
        key = bytes(key, "utf-8")
    iv_len = 16
    assert len(content) >= (iv_len + 16)
    iv = content[:iv_len]
    enc_content = content[iv_len:]
    backend = default_backend()
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
    unpadder = padding.PKCS7(128).unpadder()
    decryptor = cipher.decryptor()
    dec_content = decryptor.update(enc_content) + decryptor.finalize()
    real_content = unpadder.update(dec_content) + unpadder.finalize()
    return real_content

我们可以随机生成一些message测试下加解密:

import random

import unittest
import time
from app.libs.crypto_enc import *
from app.libs.crypto_sign import *


class TestAESEnc(unittest.TestCase):

    def test_aes_enc_dec(self):
        key = get_random_key_readable()
        print("start test_aes_enc_dec")
        total_len = 0
        s = time.time()
        for i in range(100):
            mlen = random.randint(1, 1024*1024)
            total_len += mlen
            message = os.urandom(mlen)
            enc = aes_cbc_encrypt(message, key)
            dec = aes_cbc_decrypt(enc, key)
            self.assertEqual(message, dec, "aes message len {} is not equal".format(mlen))
        e = time.time()
        print("total_len", total_len)
        print("total_time", e - s)
        print("speed", total_len / (e - s))

if __name__ == "__main__":
    unittest.main()

注意这里的速度测试是不准的, 因为包含了urandom的时间, 而这个方法比较耗时.
但是仍然可以看到, AES的加解密速度是极快的.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41298.html

相关文章

  • 最新版-Python和Java实现Aes相互解密

    摘要:前情需要使用和实现同一个加解密算法,使版本加密的密文能够由代码解密,反之亦然。加密使用模式,需要一个向量,可增加加密算法的强度此处使用做转码。解密先用解密再将代码加密出来的密钥放到中进行解密大功告成,实现了在和的互转。 前情 需要使用Python和Java实现同一个AES加解密算法,使Python版本加密的密文能够由Java代码解密,反之亦然。 Python实现 Python为3.6版...

    fox_soyoung 评论0 收藏0
  • 最新版-Python和Java实现Aes相互解密

    摘要:前情需要使用和实现同一个加解密算法,使版本加密的密文能够由代码解密,反之亦然。加密使用模式,需要一个向量,可增加加密算法的强度此处使用做转码。解密先用解密再将代码加密出来的密钥放到中进行解密大功告成,实现了在和的互转。 前情 需要使用Python和Java实现同一个AES加解密算法,使Python版本加密的密文能够由Java代码解密,反之亦然。 Python实现 Python为3.6版...

    孙淑建 评论0 收藏0
  • java解密实例

    摘要:序本文主要小结一下里头的以及加解密。属于块加密,块加密中有等几种工作模式。与一样在加密前需要对数据进行填充,不是很适合对流数据进行加密。 序 本文主要小结一下java里头的AES以及RSA加解密。 AES showImg(https://segmentfault.com/img/remote/1460000011156406);使用AES加密时需要几个参数: 密钥长度(Key Size...

    mengera88 评论0 收藏0
  • web开发安全之请求及返回流数据解密实践

    摘要:以上为加解密在实际开发过程中代码,代码提交是对于和等符号进行过滤,防止注入,在开发过程中可以参考此代码进行适当修改进行使用 web开发过程中对post请求过来的整个请求流数据,怎样保证post在传输过程中被截取后无法获取到用户提交请求实际数据,保证请求安全,在实践过程中我们采用过滤器(Filter)来实现流截取完成这个代码post请求流数据及返回数据加解密 一、请求数据流解密 1 请求...

    Taonce 评论0 收藏0
  • web开发安全之请求及返回流数据解密实践

    摘要:以上为加解密在实际开发过程中代码,代码提交是对于和等符号进行过滤,防止注入,在开发过程中可以参考此代码进行适当修改进行使用 web开发过程中对post请求过来的整个请求流数据,怎样保证post在传输过程中被截取后无法获取到用户提交请求实际数据,保证请求安全,在实践过程中我们采用过滤器(Filter)来实现流截取完成这个代码post请求流数据及返回数据加解密 一、请求数据流解密 1 请求...

    Shonim 评论0 收藏0

发表评论

0条评论

harryhappy

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<