【RSA+AES加解密实际使用浅析】

对称加密和非对称加密
对称加密:解密和加密都使用一个密钥。这样如果在传输过程中,或者在客户端的密钥被泄露,就会存在整个传输内容泄密的情况发生。显然这种加密方式是存在问题的。

非对称加密:非对称加密的加密和解密使用不同的密钥,分为公钥和私钥。公钥和私钥是成对出现的。公钥加密的数据,只有对应的私钥才能解密。私钥加密的程序只有对应的公钥才能解密。一般讲私钥存在服务器,公钥可以存在每个客户端。服务器向客户端发数据,由私钥加密数据,然后由客户端公钥解密。客户端向服务器发数据,由公钥加密,由私钥解密。整个过程中不存在传输密钥的情况,也就不会造成密钥的丢失。

对称加密和非对称加密的对比
安全性:
非对称加密依赖一对密钥,不存在传输问题,不易被第三方获取,安全性更高,算法更复杂。对称加密仅依赖一个密钥,安全性低。
加密速度:
非对称加密依赖复杂算法,速度较慢,因此只适合加密较短内容。对称加密速度较快,适合加密长数据

对称加密+非对称加密实际使用过程
1、客户端去请求服务器的公钥(rsaPublicKey),由服务器生成密钥对,服务器存公钥(rsaPublicKey)和私钥(rsaPrivateKey),将公钥发送给客户端(这一步一般会提供接口进行获取GetPubKey)
2、客户端拿到公钥,保存公钥;
3、客户端使用公钥对密码进行加密

def rsaEncrypt_PEM_RSA(content, key):
    # Encrypts the given message using PKCS#1 v1.5
    # -----BEGIN PUBLIC KEY-----
    # MIGfMA0GC244234244fdSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM6dGIA2naE3nGXi6O9vHskRSj
    # uC5hn30msl+bk1yJl4NUqH1uhzjhgsk1et7S3C0NWMDHPkC0vyWtp8HTpV1bFN747zToegLOs
    # n1+zsf1LSObVce+UU76wSHGzijksdHUWQd1J3oAHBPCHSTt+WuTe+FMbQzvX1CQAdzdqCvYFvb
    # +L+ajto9raO0cfUYHG
    # -----END PUBLIC KEY-----
    public_key = '-----BEGIN PUBLIC KEY-----\n' + key + '\n-----END PUBLIC KEY-----'
    print(public_key)
    rsakey = RSA.importKey(public_key)  # 导入读取到的公钥
    cipher = PKCS1_v1_5.new(rsakey)  # 生成对象
    # 通过生成的对象加密message明文,注意,在python3中加密的数据必须是bytes类型的数据,不能是str类型的数据
    cipher_text = base64.b64encode(cipher.encrypt(content.encode("utf-8")))
    return cipher_text

4、客户端准备发起请求,首先生成随机aes密钥(aesKey);

def generate_key():
    # 密钥长度可以为128位(16字节)、192位(24字节)、256位(32字节),根据密钥长度的不同,AES分为AES-128、AES-192、AES-256三种
    # return get_random_bytes(32).decode('utf-8')
    base64_bytes = base64.b64encode(get_random_bytes(32))
    return base64_bytes.decode('utf-8')

6、客户端正式发起请求,将加密后密码及AES秘钥传给服务器

data = {"UserName": url.Account, "Pwd": RAS_PWD.decode(), "AES": url.AES_KEY}
requests.post(url.Base_uri + url.Login_uri, data=data)
result = json.loads(response.text)
token_dict[json.loads(result["Content"])["Key"]] = json.loads(result["Content"])["Value"]
token = token_dict

7、服务器收到请求,通过rsa的私要进行解析,确认用户鉴权成功,返回认证的token,并将AES的key保存至服务器
8、通过RSA的非对称加密获取到token后,其余接口使用token进行认证,业务中需要加密或解密时统一使用AES秘钥进行对称加密

AES加解密方法(python)

import base64
import binascii
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes

# 使用ECB模式加密
MODE = AES.MODE_ECB
# 使用默认的pkcs7 padding
# PKCS7:填充字符串由一个字节序列组成,每个字节填充该字节序列的长度
PAD_STYLE = 'pkcs7'
ENCODING = 'UTF-8'

def generate_key():
    # 密钥长度可以为128位(16字节)、192位(24字节)、256位(32字节),根据密钥长度的不同,AES分为AES-128、AES-192、AES-256三种
    # return get_random_bytes(32).decode('utf-8')
    base64_bytes = base64.b64encode(get_random_bytes(32))
    return base64_bytes.decode('utf-8')

def encrypt(plaintext: str, key: str) -> str:
    # 将密钥编码为UTF-8格式的bytes
    # key_bytes = key.encode(ENCODING)
    key_bytes = base64.b64decode(key.encode(ENCODING))
    # 创建AES对象
    cipher = AES.new(key_bytes, MODE)
    # 将明文编码为UTF-8格式的bytes
    plaintext_bytes = plaintext.encode(ENCODING)
    # 为编码后的明文添加padding
    plaintext_bytes_padded = pad(plaintext_bytes, AES.block_size, PAD_STYLE)
    # 执行加密
    ciphertext_bytes = cipher.encrypt(plaintext_bytes_padded)
    # 将加密后的bytes进行base64编码
    ciphertext_base64_bytes = base64.b64encode(ciphertext_bytes)
    # 将base64编码过的bytes,解码为Python中使用的字符串类型(即unicode字符串)
    ciphertext = ciphertext_base64_bytes.decode(ENCODING)
    return ciphertext

def decrypt(ciphertext: str, key: str) -> str:
    # 将密钥编码为UTF-8格式的bytes
    # key_bytes = key.encode(ENCODING)
    key_bytes = base64.b64decode(key.encode(ENCODING))
    # 创建AES对象
    decrypter = AES.new(key_bytes, MODE)
    # 将密文编码为UTF-8格式的(同时也是base64编码的)bytes
    ciphertext_base64_bytes = ciphertext.encode(ENCODING)
    # 将base64编码的bytes,解码为原始的密文bytes
    ciphertext_bytes = base64.b64decode(ciphertext_base64_bytes)
    # 解码为明文
    plaintext_bytes_padded = decrypter.decrypt(ciphertext_bytes)
    # 去掉Padding
    plaintext_bytes = unpad(plaintext_bytes_padded, AES.block_size, PAD_STYLE)
    # 将UTF-8格式编码的明文bytes,解码为Python中的字符串类型(即unicode字符串)
    plaintext = plaintext_bytes.decode(ENCODING)
    return plaintext
    
if __name__ == '__main__':
    key = generate_key()
    print("AES密钥:{}".format(key))
    string_w = "hello world!~"
    print("解密前数据:{}".format(string_w))
    res = encrypt(string_w, key)
    print("加密后数据:{}".format(res))
    print("解密后数据:{}".format(decrypt(res, key)))


AES密钥:vhDfeMHxbvMiJMv0Tc/uSHBmOVqTSNYBxMymlUvJ2vg=
解密前数据:hello world!~
加密后数据:C993IuOo9FuFQa/UnezEkA==
解密后数据:hello world!~

RSA通过公钥或模及指数加密方法(python)

import rsa
import base64
import binascii
from ctl.core.HandleLog.handle_log import log
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa as cryptography_rsa, padding

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5


def rsaEncrypt_PEM_RSA(content, key):
    # Encrypts the given message using PKCS#1 v1.5
    # -----BEGIN PUBLIC KEY-----
    # MIGfMA0GC244234244fdSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM6dGIA2naE3nGXi6O9vHskRSj
    # uC5hn30msl+bk1yJl4NUqH1uhzjhgsk1et7S3C0NWMDHPkC0vyWtp8HTpV1bFN747zToegLOs
    # n1+zsf1LSObVce+UU76wSHGzijksdHUWQd1J3oAHBPCHSTt+WuTe+FMbQzvX1CQAdzdqCvYFvb
    # +L+ajto9raO0cfUYHG
    # -----END PUBLIC KEY-----
    public_key = '-----BEGIN PUBLIC KEY-----\n' + key + '\n-----END PUBLIC KEY-----'
    print(public_key)
    rsakey = RSA.importKey(public_key)  # 导入读取到的公钥
    cipher = PKCS1_v1_5.new(rsakey)  # 生成对象
    # 通过生成的对象加密message明文,注意,在python3中加密的数据必须是bytes类型的数据,不能是str类型的数据
    cipher_text = base64.b64encode(cipher.encrypt(content.encode("utf-8")))
    return cipher_text

def rsaEncrypt_PKCS_1_5_RSA(content, rsaModulus, rsaExponent):
    # Encrypts the given message using PKCS#1 v1.5
    result = rsa.encrypt(content.encode(),
        rsa.PublicKey(
            int(binascii.b2a_hex(base64.b64decode(rsaModulus)), 16),
            int(binascii.b2a_hex(base64.b64decode(rsaExponent)), 16)
        )
    )
    return base64.b64encode(result)

def rsaEncrypt_PKCS_1_5_Crypto(content, public_exponent, modulus=None):
    # Encrypts the given message using PKCS1_v1_5
    e = int(binascii.b2a_hex(base64.b64decode(public_exponent)), 16)  # 指数
    n = int(binascii.b2a_hex(base64.b64decode(modulus)), 16)
    rsa_key = RSA.construct((n, e))  # generate/export
    # public key
    public_key = rsa_key.publickey()
    cipher = PKCS1_v1_5.new(public_key)
    cipher_text = base64.b64encode(cipher.encrypt(content.encode("utf-8")))
    return cipher_text


def rsa_encrypt(rsa_n: str, rsa_e: str, msg: str):
    """
    :param rsa_n: rsa n
    :param rsa_e: rsa e
    :param msg: encryt str
    :return:
    """
    rsa_n = int(binascii.b2a_hex(base64.b64decode(rsa_n)), 16)
    rsa_e = int(binascii.b2a_hex(base64.b64decode(rsa_e)), 16)
    pubkey = cryptography_rsa.RSAPublicNumbers(rsa_e, rsa_n).public_key(default_backend())
    key = pubkey.encrypt(msg.encode('utf-8'), padding.PKCS1v15())
    # key = pubkey.encrypt(msg.encode('utf-8'), padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None))
    # return str(binascii.b2a_base64(key))
    return base64.b64encode(key)

def public_key(rsaExponent, rsaModulus, msg):
    e = int(binascii.b2a_hex(base64.b64decode(rsaExponent)), 16)
    n = int(binascii.b2a_hex(base64.b64decode(rsaModulus)), 16)  # snipped for brevity
    # pubkey = construct((n, e))
    pubkey = rsa.RSAPublicNumbers(e, n).public_key(default_backend())
    # pubkey = rsa.RSAPublicNumbers(e, n).public_key()
    key = pubkey.encrypt(msg.encode('utf-8'), padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None))
    log.info(str(binascii.b2a_base64(key)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值