python 实现AES加密解密(对称加密、ECB模式,配合base64)

什么是对称加密

什么叫对称加密呢,你可以这么理解,一方通过密钥将信息加密后,把密文传给另一方,另一方通过这个相同的密钥将密文解密,转换成可以理解的明文。

什么是非对称加密

  • A要向B发送信息,A和B都要产生一对用于加密和解密的公钥和私钥。
  • A的私钥保密,A的公钥告诉B;B的私钥保密,B的公钥告诉A。
  • A要给B发送信息时,A用B的公钥加密信息,因为A知道B的公钥。
  • A将这个消息发给B(已经用B的公钥加密消息)。
  • B收到这个消息后,B用自己的私钥解密A的消息,其他所有收到这个报文的人都无法解密,因为只有B才有B的私钥。
  • 反过来,B向A发送消息也是一样。

对称加密和非对称加密的对比:

对称加密加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以
安全性不高。

  • 非对称加密使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。
  • 解决的办法是将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通

什么是AES:

AES 算法全称是 Advanced Encryption Standard,是DES 算法的替代者,也是现在最流行的对称加密算法之一。

AES的加密流程:

1.把明文按照128bit拆分成若干个明文块。
2.按照选择的填充方式来填充最后一个明文块。
3.每一个明文块利用AES加密器和密钥,加密成密文块。
4.拼接所有的密文块,成为最终的密文结果。

AES加密三要素:

想要搞明白AES算法,首先要搞清楚三个基本概念。
秘钥,填充,模式。

1.秘钥:
对称加密之所以对称就是因为这类算法对明文的加密和解密使用的是同
一个密钥。
AES支持三种长度的密钥:128位,192位,256位

2.填充:

说到填充一定要说一下,AES 分组加密的特性,AES 加密并不是一股脑将明文加密成密文的,而是把明文拆分成一个个独立的明文块,且每个明文块128bit。
假如一段明文长度是196bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit。这时候怎么办呢?就需要对明文块
进行填充(Padding)。

填充的类型:(主要用到的有前三种)
• NoPadding
• PKCS7Padding
• ZeroPadding
• AnsiX923
• Iso10126
• Iso97971

3.模式:

AES的工作模式,体现在把明文块加密成密文块的处理过程中。AES加密算法提供了五种不同的工作模式:
ECB、CBC、CTR、CFB、OFB
模式之间的主题思想是近似的,在处理细节上有一些差别。

ECB模式:

ECB模式(Electronic Codebook Book)是最简单的工作模式,在该模式下,每一个明文块的加密都是完全独立,互不干涉的。
这样的好处是什么呢?
1.简单
2.有利于并行计算
缺点同样也很明显:
相同的明文块经过加密会变成相同的密文块,因此安全性较差。

CBC模式:

CBC模式(Cipher Block Chaining)引入了一个新的概念:初始向量IV(Initialization Vector)。
IV是做什么用的呢?它的作用和MD5的“加盐”有些类似,目的是防止同样的明文块始终加密成同样的密文块。
CBC模式在每一个明文块加密前会让明文块和一个值先做异或操作。
IV作为初始化变量,参与第一个明文块的异或,后续的每一个明文块和它 前一个明文块所加密出的密文块相异或。
这样相同的明文块加密出的密文块显然是不一样的。
CBC模式的好处是什么呢?安全性更高
坏处也很明显:
1.无法并行计算,性能上不如ECB
2.引入初始化向量IV,增加复杂度。

用JavaScript实现AES加密的脚本:

var CryptoJS = require("crypto-js");
var key ="ABC123456789";    //秘钥
var iv = "1234567812345678";  //初始向量IV
function encrypt(text){
    return CryptoJS.AES.encrypt(text,CryptoJS.enc.Utf8.parse(key),{
        iv:CryptoJS.enc.Utf8.parse(iv),
        mode:CryptoJS.mode.CBC,  // CBC模式
        padding:CryptoJS.pad.Pkcs7 // 这里选择的填充类型为Pkcs7 ,还可能是ZeroPadding    NoPadding
    })
}
function decrypt(text){
    var result = CryptoJS.AES.decrypt(text,CryptoJS.enc.Utf8.parse(key),{
        iv:CryptoJS.enc.Utf8.parse(iv),
        mode:CryptoJS.mode.CBC,  //解密的模式必须和加密的模式相同,包括填充类型也需要相同。
        padding:CryptoJS.pad.Pkcs7
    })
    return result.toString(CryptoJS.enc.Utf8)
}
var text="测试AES加密";
var encoded=encrypt(text)
console.log(encoded.toString());
console.log(decrypt(encoded))

ECB模式下的,python代码实现的例子

import base64
from Crypto.Cipher import AES
 
'''
采用AES对称加密算法
'''
# str不是32的倍数那就补足为16的倍数
def add_to_32(value):
    while len(value) % 32 != 0:
        value += '\0'
    return str.encode(value)  # 返回bytes
 
def add_to_16(value):
    while len(value) % 16 != 0:
        value += '\0'
    return str.encode(value)  # 返回bytes
 
#加密方法
def encrypt_oracle(text):
    # 秘钥
    key = 'VW1lMjAxMlRyaXAwMzA5AA=='
    # 待加密文本
    # 初始化加密器
    aes = AES.new(add_to_16(key), AES.MODE_ECB)
    #先进行aes加密
    encrypt_aes = aes.encrypt(add_to_16(text))
    #用base64转成字符串形式
    encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8')  # 执行加密并转码返回bytes
    print(encrypted_text)
    return encrypted_text
#解密方法
def decrypt_oralce(text):
    # 秘钥
    key = 'VW1lMjAxMlRyaXAwMzA5AA=='
    # 密文
    # 初始化加密器
    aes = AES.new(add_to_16(key), AES.MODE_ECB)
    #优先逆向解密base64成bytes
    base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8'))
    #执行解密密并转码返回str
    decrypted_text = str(aes.decrypt(base64_decrypted),encoding='utf-8').replace('\0','')
    print('decrypted_text',decrypted_text)
    return decrypted_text
 
if __name__ == '__main__':
 
    text = '''{'aaa': '111', 'bbb': '222'}'''
    entrypted_text = encrypt_oracle(text)
 
    decrypt_oralce(entrypted_text)

注意key是16位或者32位的,选择对应的key加密函数。

—————————————————————————————————————————————

原文链接:https://blog.csdn.net/xiongzaiabc/article/details/97528041

转载仅是用于自己方便查阅、学习

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 下面是使用 Python 实现 AES 加密和解密的示例代码: ``` import base64 import hashlib import os from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding, serialization from cryptography.hazmat.primitives.ciphers import ( Cipher, algorithms, modes ) def generate_key(password: str, salt: bytes, iterations: int = 100000, key_size: int = 32): kdf = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, iterations, key_size) return kdf def encrypt(plaintext: str, password: str, salt: bytes): # Generate key key = generate_key(password, salt) # Add padding to the plaintext padder = padding.PKCS7(algorithms.AES.block_size).padder() padded_plaintext = padder.update(plaintext.encode()) + padder.finalize() # Generate a random IV iv = os.urandom(16) # Encrypt the plaintext cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize() # Concatenate the IV and the ciphertext encrypted_message = iv + ciphertext # Encode the encrypted message as a base64 string encoded_encrypted_message = base64.b64encode(encrypted_message) return encoded_encrypted_message def decrypt(encoded_encrypted_message: str, password: str, salt: bytes): # Decode the encrypted message from a base64 string encrypted_message = base64.b64decode(encoded_encrypted_message) # Split the IV and the ciphertext iv = encrypted_message[:16] ciphertext = encrypted_message[16:] # Generate key key = generate_key(password, salt) # Decrypt the ciphertext cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize() # Remove padding from the plaintext unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() plaintext = unpadder.update(padded_plaintext) + unpadder.finalize() return plaintext.decode() ``` 使用示例: ``` password = "secret password" salt = b"salt" plaintext = "hello world" encoded_encrypted_message = encrypt(plaintext, password, salt) print("Encrypted message:", encoded_encrypted_message) decrypted_plaintext = decrypt(encoded_encrypted_message, ### 回答2: 使用Python实现AES加密和解密可以使用PyCryptodome库。首先需要安装PyCryptodome库,使用pip安装命令:pip install pycryptodome。 以下是使用Python实现AES加密和解密的示例代码: ```python from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from Crypto.Util.Padding import pad, unpad # 定义密钥和初始化向量 key = get_random_bytes(16) iv = get_random_bytes(16) def encrypt(plaintext): cipher = AES.new(key, AES.MODE_CBC, iv) ciphertext = cipher.encrypt(pad(plaintext.encode(), AES.block_size)) return ciphertext def decrypt(ciphertext): cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size) return plaintext.decode() # 测试加密和解密功能 plaintext = "Hello, AES!" print("Plaintext:", plaintext) ciphertext = encrypt(plaintext) print("Ciphertext:", ciphertext) decrypted_text = decrypt(ciphertext) print("Decrypted Text:", decrypted_text) ``` 这个示例代码实现AES加密和解密的功能。首先定义了一个随机生成的16字节密钥和初始化向量。然后定义了`encrypt`函数和`decrypt`函数分别用于加密和解密。 在加密函数中,使用AES.MODE_CBC模式创建了一个AES加密器,并使用密钥和初始化向量进行初始化。然后使用`pad`函数对明文进行填充,并调用加密器的`encrypt`方法进行加密。 在解密函数中,同样使用AES.MODE_CBC模式创建一个AES解密器,并使用密钥和初始化向量进行初始化。解密器调用`decrypt`方法对密文进行解密,并使用`unpad`函数去除填充。 最后,测试加密和解密功能。将明文传递给`encrypt`函数进行加密,得到密文。然后将密文传递给`decrypt`函数进行解密,得到原始的明文。 请注意,这个示例代码中的密钥和初始化向量是随机生成的,每次运行代码都会生成不同的密钥和向量。在实际应用中,应该将密钥和向量保存下来,以便在解密时使用相同的密钥和向量。 ### 回答3: 在Python中,可以使用Crypto库来实现AES加密和解密功能。首先需要安装Crypto库,可以使用pip命令进行安装。 加密过程如下: ``` from Crypto.Cipher import AES def encrypt(plain_text, key): cipher = AES.new(key, AES.MODE_ECB) encrypted_text = cipher.encrypt(plain_text) return encrypted_text key = b'1234567890123456' # 16字节的密钥 plain_text = b'Hello World!' # 待加密的明文 encrypted_text = encrypt(plain_text, key) print('加密后的结果:', encrypted_text) ``` 解密过程如下: ``` from Crypto.Cipher import AES def decrypt(encrypted_text, key): cipher = AES.new(key, AES.MODE_ECB) plain_text = cipher.decrypt(encrypted_text) return plain_text key = b'1234567890123456' # 16字节的密钥 encrypted_text = b'\xd6#\x82\xa9W\x8c\xf1\x15J\'=0\xe8\x99' # 待解密的密文 decrypted_text = decrypt(encrypted_text, key) print('解密后的结果:', decrypted_text) ``` 需要注意的是,使用AES进行加密和解密时,需要保证密钥的长度是16、24或32字节,分别对应AES-128、AES-192和AES-256算法。此外,AES是一个对称加密算法,加密和解密需要使用相同的密钥。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值