AES对称加密与RSA非对称加密

AES对称加密

加密方式:AES算法,基本变换包括SubBytes(字节替代)、ShiftRows(行移位)、MixColumns(列混淆)、AddRoundKey(轮密钥加)。

加密模式:

CBC模式:通过密钥和salt(起扰乱作用)按固定算法(md5)产生key和iv。然后用key和iv(初始向量,加密第一块明文)加密(明文)和解密(密文)。

ECB模式:不需要iv偏移量

python中使用到的库:

from Crypto.Cipher import AES

安装:

**Linux**下使用AES时要安装的是pycrypto模块  pip install pycrypto

**Windows**下使用AES时要安装的是pycryptodome 模块  pip install pycryptodome

实际使用:

1、准备key,可以理解成加密解密的密码

2、加密后还会使用base64再次加密,当然解密时先用base64先进行第一次解密

3、还可以将base64第二次加密换成ASCII码进行加密,使用到的包如下:from binascii import b2a_hex, a2b_hex
class AESCryptoHelper():
    def encrypt(data, key):
        """
        加密时使用的key,只能是长度16,24和32的字符串
        data: 要加密的内容,bytes
        key:密钥,len必须是16, 24, 32之一 bytes
        result:加密内容,bytes
        """
        keySzie = len(key)
        if keySzie == 16 or keySzie == 24 or keySzie == 32:
            cipher = AES.new(key, AES.MODE_ECB)
            padData = AESCryptoHelper._padData(data)
            encrypted = cipher.encrypt(padData)
            result = base64.b64encode(encrypted)
            return result
        else:
            # 加密失败,返回原数据
            return data

    # 解密后,去掉补足的空格用strip() 去掉
    def decrypt(data, key):
        """
        加密时使用的key,只能是长度16,24和32的字符串
        data: 要解密的内容,bytes
        key:密钥,bytes
        result:解密的内容,bytes
        """
        keySzie = len(key)
        if keySzie == 16 or keySzie == 24 or keySzie == 32:
            cipher = AES.new(key, AES.MODE_ECB)
            tmpData = base64.b64decode(data)
            decrypted = cipher.decrypt(tmpData)
            result = AESCryptoHelper._unpadData(decrypted)
            return result
        else:
            # 解密失败,返回原数据
            return data
        
    def _padData(data):
        """
        按AES加密的要求,填充内容,使其为block_size的整数倍
        """
        block_size = 16
        padding = b"\0"
        padData = data + (block_size - len(data) % block_size) * padding
        return padData
    
    def _unpadData(data):
        """
        删除填充数据
        """
        padding = b"\0"
        index = -1
        while data[index] == padding[0]:
            index += -1
        if index != -1:
            return data[0: index+1]
        else:
            return data

RSA非对称加密

实际加密步骤:

1、生成公钥、私钥(服务器)

2、公钥加密数据得到密文,在使用base64加密密文(客户端)

3、base64逆向解码,私钥解密密文(服务器)

# -*- coding: UTF-8 -*-
# ! /usr/bin/env python
import base64
import rsa
from rsa import common

PUBLIC_KEY_PATH = '/Users/anonyper/Desktop/key/company_rsa_public_key.pem'  # 公钥
PRIVATE_KEY_PATH = '/Users/anonyper/Desktop/key/company_rsa_private_key.pem'  # 私钥

# -------------------------- 生成公私钥 --------------------------
class CreateKeys:
    def __init__(self):
        public_key, private_key = rsa.newkeys(1024)
        public_pkcs1 = public_key.save_pkcs1().decode()
        private_pkcs1 = private_key.save_pkcs1().decode()

        # 生成公钥和私钥
        with open(PUBLIC_KEY_PATH, 'w') as pub_f, open(PRIVATE_KEY_PATH, 'w') as pri_f:
            pub_f.write(public_pkcs1)
            pri_f.write(private_pkcs1)
     	print('>> 生成公私钥成功')
        
    def __str__(self):
        pass


# -------------------------- RSA签名和加解密 --------------------------
class RsaUtil(object):
    # 初始化key
    def __init__(self,
                 company_pub_file=PUBLIC_KEY_PATH,
                 company_pri_file=PRIVATE_KEY_PATH):

        if company_pub_file:
            self.company_public_key = rsa.PublicKey.load_pkcs1(open(company_pub_file).read())
        if company_pri_file:
            self.company_private_key = rsa.PrivateKey.load_pkcs1(open(company_pri_file).read())

    def get_max_length(self, rsa_key, encrypt=True):
        """加密内容过长时 需要分段加密 换算每一段的长度.
            :param rsa_key: 钥匙.
            :param encrypt: 是否是加密.
        """
        blocksize = common.byte_size(rsa_key.n)
        reserve_size = 11  # 预留位为11
        if not encrypt:  # 解密时不需要考虑预留位
            reserve_size = 0
        maxlength = blocksize - reserve_size
        return maxlength

    # 加密 支付方公钥
    def encrypt_by_public_key(self, message):
        """使用公钥加密.
            :param message: 需要加密的内容.
            加密之后需要对接过进行base64转码
        """
        encrypt_result = b''
        max_length = self.get_max_length(self.company_public_key)
        while message:
            input = message[:max_length]
            message = message[max_length:]
            out = rsa.encrypt(input, self.company_public_key)
            encrypt_result += out
        encrypt_result = base64.b64encode(encrypt_result)
        return encrypt_result

    def decrypt_by_private_key(self, message):
        """使用私钥解密.
            :param message: 需要加密的内容.
            解密之后的内容直接是字符串,不需要在进行转义
        """
        decrypt_result = b""

        max_length = self.get_max_length(self.company_private_key, False)
        decrypt_message = base64.b64decode(message)
        while decrypt_message:
            input = decrypt_message[:max_length]
            decrypt_message = decrypt_message[max_length:]
            out = rsa.decrypt(input, self.company_private_key)
            decrypt_result += out
        return decrypt_result

    # 签名 商户私钥 base64转码
    def sign_by_private_key(self, data):
        """私钥签名.
            :param data: 需要签名的内容.
            使用SHA-1 方法进行签名(也可以使用MD5)
            签名之后,需要转义后输出
        """
        signature = rsa.sign(str(data), priv_key=self.company_private_key, hash='SHA-1')
        return base64.b64encode(signature)

    def verify_by_public_key(self, message, signature):
        """公钥验签.
            :param message: 验签的内容.
            :param signature: 对验签内容签名的值(签名之后,会进行b64encode转码,所以验签前也需转码).
        """
        signature = base64.b64decode(signature)
        return rsa.verify(message, signature, self.company_public_key)

CreateKeys()
message = 'hell world'
print("明文内容:>>> ")
print(message)
rsaUtil = RsaUtil()
encrypy_result = rsaUtil.encrypt_by_public_key(message)
print("加密结果:>>> ")
print(encrypy_result)
decrypt_result = rsaUtil.decrypt_by_private_key(encrypy_result)
print("解密结果:>>> ")
print(decrypt_result)
sign = rsaUtil.sign_by_private_key(message)
print("签名结果:>>> ")
print(sign)
print("验签结果:>>> ")
print(rsaUtil.verify_by_public_key(message, sign))

缓存实现连个两个接口数据

使用缓存机制可以实现后端两个接口的开关控制,如实现以下功能:

		浏览器获取手机上传的数据,当获取到数据后不刷新界面。

在程序中实现如下:

		1、**浏览器**不断请求存放数据的接口(浏览器无法判断数据是否是新数据还是旧数据,所以只要有数据页面就会不断刷新),

		2、**手机**上传数据,调用存放数据的接口,

		很明显手机上传数据的接口与浏览器下载数据的接口不是同一个,所以两个接口数据无法连接起来。

使用缓存可以实现两个接口数据的传输,步骤如下:

		1、手机将数据存储到给某个id分配的缓存内,当浏览器发送请求时,从缓存提取这个id的缓存数据。

数据通信实现了,那么如何实现旧数据不刷新,新数据才刷新呢。

		1、很简单,设置一个update的键值对,手机上传说明有新数据设置为True,当浏览器获取了数据就将update设置为False,这样就实现了开关功能。

使用缓存最大的好处是可以定时删除数据。

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
双向 RSA + AES 加密是一种常见的加密方式,其中使用 RSA 算法加密 AES 密钥,然后使用 AES 算法加密数据。在 C# 中,可以使用 `RSACryptoServiceProvider` 类和 `AesCryptoServiceProvider` 类来实现此加密方式。以下是一个简单的示例: ```csharp using System; using System.IO; using System.Security.Cryptography; using System.Text; class Program { static void Main(string[] args) { string plainText = "Hello, world!"; byte[] encryptedData = Encrypt(plainText); string decryptedText = Decrypt(encryptedData); Console.WriteLine("Original text: {0}", plainText); Console.WriteLine("Encrypted data: {0}", Convert.ToBase64String(encryptedData)); Console.WriteLine("Decrypted text: {0}", decryptedText); } static byte[] Encrypt(string plainText) { byte[] aesKey = GenerateAesKey(); using (var rsa = new RSACryptoServiceProvider()) { rsa.PersistKeyInCsp = false; byte[] encryptedAesKey = rsa.Encrypt(aesKey, true); // 使用 RSA 加密 AES 密钥 using (var aes = new AesCryptoServiceProvider()) { aes.Key = aesKey; aes.GenerateIV(); using (var memoryStream = new MemoryStream()) { memoryStream.Write(aes.IV, 0, aes.IV.Length); using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write)) { byte[] plainData = Encoding.UTF8.GetBytes(plainText); cryptoStream.Write(plainData, 0, plainData.Length); cryptoStream.FlushFinalBlock(); } byte[] encryptedData = memoryStream.ToArray(); byte[] result = new byte[encryptedAesKey.Length + encryptedData.Length]; Buffer.BlockCopy(encryptedAesKey, 0, result, 0, encryptedAesKey.Length); Buffer.BlockCopy(encryptedData, 0, result, encryptedAesKey.Length, encryptedData.Length); return result; } } } } static string Decrypt(byte[] encryptedData) { byte[] encryptedAesKey = new byte[128]; // RSA 加密 AES 密钥得到的密文长度为 128 字节 byte[] encryptedDataOnly = new byte[encryptedData.Length - encryptedAesKey.Length]; Buffer.BlockCopy(encryptedData, 0, encryptedAesKey, 0, encryptedAesKey.Length); Buffer.BlockCopy(encryptedData, encryptedAesKey.Length, encryptedDataOnly, 0, encryptedDataOnly.Length); using (var rsa = new RSACryptoServiceProvider()) { rsa.PersistKeyInCsp = false; byte[] aesKey = rsa.Decrypt(encryptedAesKey, true); // 使用 RSA 解密 AES 密钥 using (var aes = new AesCryptoServiceProvider()) { aes.Key = aesKey; aes.IV = encryptedDataOnly.Take(aes.IV.Length).ToArray(); using (var memoryStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Write)) { cryptoStream.Write(encryptedDataOnly, aes.IV.Length, encryptedDataOnly.Length - aes.IV.Length); cryptoStream.FlushFinalBlock(); } byte[] decryptedData = memoryStream.ToArray(); return Encoding.UTF8.GetString(decryptedData); } } } } static byte[] GenerateAesKey() { using (var aes = new AesCryptoServiceProvider()) { aes.GenerateKey(); return aes.Key; } } } ``` 上面的代码中,首先调用 `GenerateAesKey` 方法生成 AES 密钥,然后使用 RSA 算法加密 AES 密钥。加密时,先将 AES 密钥使用 RSA 加密,然后使用 AES 算法加密数据。具体来说,将 AES 密钥和 IV 都写入 `MemoryStream` 对象中,然后使用 `CryptoStream` 对象将数据写入 `MemoryStream` 对象中。最后将密文和 RSA 加密的 AES 密钥一起返回。 解密时,先从密文中取出 RSA 加密的 AES 密钥,然后使用 RSA 算法解密 AES 密钥。解密时,先从密文中取出 AESIV 值,然后使用 `CryptoStream` 对象将数据解密。最后将解密后的文本返回。 注意,上面的示例仅用于演示 RSA + AES 加密的基本原理,实际使用中还需要考虑安全性等因素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值