Python代码实现MD5、AES对称加密和RSA非对称加密以及OpenSSl实践

本文介绍了MD5的特性、应用及简单的Python实现,指出其不安全性。接着讲解了AES对称加密的过程、代码实现,强调了其高效但安全性相对较低。然后讨论了RSA非对称加密的概念、优势和代码示例,指出其更高的安全性。最后提到了数字签名和数字证书在验证数据完整性和身份认证中的作用。
摘要由CSDN通过智能技术生成

1、MD5加密算法

1.1 MD5加密的特点

  • 不可逆运算
  • 对不同的数据加密的结果是定长的32位和16位字符(不管文件多大都一样)
  • 对相同的数据加密,得到的结果是一样的(也就是复制)。
  • 抗修改性 :信息“指纹”,对原数据进行任何改动,哪怕只修改一个字节,所得到的 MD5 值都有很大区别
  • 弱抗碰撞 :已知原数据和其 MD5 值,想找到一个具有相同 MD5 值的数据(即伪造数据)是非常困难的.
  • 强抗碰撞: 想找到两个不同数据,使他们具有相同的 MD5 值,是非常困难的

1.2 MD5 应用

  • 一致性验证:MD5将整个文件当做一个大文本信息,通过不可逆的字符串变换算法,产生一个唯一的MD5信息摘要,就像每个人都有自己独一无二的指纹,MD5对任何文件产生一个独一无二的数字指纹。
  • 那么问题来了,你觉得这个MD5加密安全吗?其实是不安全的,无论加密多好次,得到的密文都是固定值
  • MD5在线参考网站:https://www.lddgo.net/encrypt/md5

在这里插入图片描述

1.3 代码实现

需要引入hashlib库。

代码如下:

import hashlib

arg = '测试同学'
print(arg)
# MD5加密的实现形式
se = hashlib.md5(arg.encode('utf-8'))
# 获取变量的内存地址
print(se)
# 获取加密后的密文值
print(se.hexdigest())

运行结果:

测试同学
<md5 _hashlib.HASH object @ 0x0000024125FDF230>
25d5b7a6843ed38132eafcf17cd2a76a

代码封装一下:

import hashlib

# md5加密的封装函数
def hashmd5(arg):
    return hashlib.md5(arg.encode('utf-8')).hexdigest()

if __name__ == '__main__':
    se2 = hashmd5("测试同学")
    print(se2)

2、AES对称加密和解密

2.1 什么是对称加密?

在对称加密算法中,加密和解密使用的是同一把钥匙,即:使用相同的密匙对同一密码进行加密和解密;

2.2 加密过程

发送方(原文)——秘钥加密——>密文———秘钥解密———> 接收方(原文)

加密:原文 + 秘钥 = 密文
解密:密文 - 秘钥 = 原文

发送方发送的原文,通过秘钥加密后的密文发送给接收方,接收方用同一把秘钥解密后得到原文。

2.3 环境安装

我使用的是Python3,安装pycryptodome。安装前最好卸载crypto 和 pycrypto,不然会有报错。

pip uninstall crypto
pip uninstall pycrypto
pip install pycryptodome

2.4 AES加密在线参考网站

https://www.lddgo.net/encrypt/aes

AES加密:
在这里插入图片描述
AES解密:
在这里插入图片描述

2.5 代码实现

import base64
from Crypto.Cipher import AES


class EncryptDate:
    def __init__(self, key):
        self.key = key.encode("utf-8")  # 初始化密钥
        self.length = AES.block_size  # 初始化数据块大小
        self.aes = AES.new(self.key, AES.MODE_ECB)  # 初始化AES,ECB模式的实例
        # 截断函数,去除填充的字符
        self.unpad = lambda date: date[0:-ord(date[-1])]

    def pad(self, text):
        """
        # 填充函数,使被加密数据的字节码长度是block_size的整数倍
        """
        count = len(text.encode('utf-8'))
        add = self.length - (count % self.length)
        entext = text + (chr(add) * add)
        return entext

    def encrypt(self, encrData):  # 加密函数
        res = self.aes.encrypt(self.pad(encrData).encode("utf8"))
        # Base64是网络上最常见的用于传输8Bit字节码的编码方式之一
        msg = str(base64.b64encode(res), encoding="utf8")
        return msg

    def decrypt(self, decrData):  # 解密函数
        res = base64.decodebytes(decrData.encode("utf8"))
        msg = self.aes.decrypt(res).decode("utf8")
        return self.unpad(msg)

if __name__ == '__main__':
    print("============加密==================")
    key = "1234567812345678"  # key 密码,服务器指定
    data = "测试同学"  # 数据
    eg = EncryptDate(key)  # 这里密钥的长度必须是16的倍数
    res = eg.encrypt(str(data))
    print(res, end='')
    print("\n============解密==================")
    data = "CFbJUXkduezgDZ7ZbO+SOw=="  # 数据
    res = eg.decrypt(str(data))
    print(res, end='')

运行结果:

============加密==================
CFbJUXkduezgDZ7ZbO+SOw==
============解密==================
测试同学

2.6 对称加密的优缺点

  • 优点:算法简单,加密解密容易,效率高,执行快。
  • 缺点:相对来说不算特别安全,只有一把钥匙,密文如果被拦截,且密钥也被劫持,那么,信息很容易被破译。

3、RSA非对称加密

3.1 什么是非对称加密?

  • 对称加密是使用同一把密钥进行加密和解密。非对称加密是使用不同的密钥进行加密和解密。
  • 非对称加密有2个钥匙,公钥和私钥。公钥和私钥成对存在。
  • 如果对原文使用公钥加密,则只能使用对应的私钥才能解密;因为加密和解密使用的不是同一把密钥,所以这种算法称之为非对称加密算法

3.2 加密过程

发送方(原文)接收方公钥加密—>密文——接收方私钥解密——> 接收方(原文)

加密:原文 + 公钥 = 密文
解密:密文 - 私钥 = 原文

3.3 非对称加密更安全

非对称加密算法的密匙是通过一系列算法获取到的一长串随机数,通常随机数的长度越长,加密信息越安全。通过私钥经过一系列算法是可以推导出公钥的,也就是说,公钥是基于私钥而存在的。但是无法通过公钥反向推倒出私钥,这个过程是单向的。

例如:接收方公钥泄露,也不会导致消息泄露,因为密文只能通过接收方的私钥才能打开。因此接收方只需要保管好自己的私钥不泄露即可。

3.4 非对称加密的优缺点:

  • 优点:安全,即使密文被拦截、公钥被获取,但是无法获取到私钥,也就无法破译密文。作为接收方,务必要保管好自己的密钥。
  • 缺点:加密算法及其复杂,安全性依赖算法与密钥,而且加密和解密效率很低

3.5 RSA在线参考网站

https://www.lddgo.net/encrypt/rsakey
https://www.lddgo.net/encrypt/rsa
在这里插入图片描述

3.6 代码实现

import base64
import rsa

# 秘钥的位数, 可以自定义指定, 例如: 128、256、512、1024、2048等
(pubkey, privkey) = rsa.newkeys(512)
# 生成公钥
pub = pubkey.save_pkcs1()
with open('public.pem', 'wb') as f:
    f.write(pub)

# # 生成私钥
pri = privkey.save_pkcs1()
with open('private.pem', 'wb') as f:
    f.write(pri)

# 公钥
pub_str = '''-----BEGIN RSA PUBLIC KEY-----
MEgCQQCte/qARce725ilnKCQ4ULrBxhECGygdUq022KUTpd/oPYHQkBCFhup7TtW
QAstYinLQQantDayhDcCTiwFYnGxAgMBAAE=
-----END RSA PUBLIC KEY-----'''

# 私钥
priv_str = '''-----BEGIN RSA PRIVATE KEY-----
MIIBPQIBAAJBAK17+oBFx7vbmKWcoJDhQusHGEQIbKB1SrTbYpROl3+g9gdCQEIW
G6ntO1ZACy1iKctBBqe0NrKENwJOLAVicbECAwEAAQJBAJ0VLjwpcvIBo5UJXkXx
AdOnx+wKKLmdmrhqETeydTqaAAYt4wdTsw6Ik03GK+JoP7/NHKCsTy+T/pv288QQ
29UCIwDJd4+LQgJcg45w+SR7jrI8xZJLS+1aC68yTsmTm2Ox6psHAh8A3HFiT2A9
JxLLEc1qrnOHcWFkXQnR8jskyr5xRoeHAiJTyZ2xVOqWf0AmS/eYS2hlTeXh2toD
sQhT6+B5uw5jWCbRAh8AjUeVrC2Pw8UFpKk0IA4m1gGHIyGyDj7de5rGWl9tAiIR
a6ls8EL2C27mnhtG2otMHUbZYnGXA5TYyw0upZ0Ogo5u
-----END RSA PRIVATE KEY-----'''

class Rsa():
    def __init__(self):
        self.pub_key = rsa.PublicKey.load_pkcs1(pub_str)
        self.priv_key = rsa.PrivateKey.load_pkcs1(priv_str)

    def encrypt(self, text):
        # rsa加密 最后把加密字符串转为base64
        text = text.encode("utf-8")
        cryto_info = rsa.encrypt(text, self.pub_key)
        cipher_base64 = base64.b64encode(cryto_info)
        cipher_base64 = cipher_base64.decode()
        return cipher_base64

    def decrypt(self, text):
        # rsa解密 返回解密结果
        cryto_info = base64.b64decode(text)
        talk_real = rsa.decrypt(cryto_info, self.priv_key)
        res = talk_real.decode("utf-8")
        return res


if __name__ == "__main__":
    rsaer = Rsa()
    info = rsaer.encrypt('测试同学')
    print('加密:', info)
    print('解密:', rsaer.decrypt(info))

运行结果:

加密: q+SEQFQj85GjfeXzK07Bqn/bddLB89LSgKiV9quih+FanhmidRLAS/asTLY3534qkXGdXNz87WkSZBfyiyEcaA==
解密: 测试同学

4、OpenSSL

4.1 SSL:套接字的安全层

4.2 功能

  • 秘钥证书管理
  • 对称加密
  • 非对称加密

4.3 环境配置

  • 下载链接
  • 将OpenSSL的bin目录配置到环境变量
  • 验证配置成功
    在这里插入图片描述

4.4 加解密命令

工具: openssl enc, gpg
算法: 3des, aes, blowfish, twofish、3des等。
常用选项有:
-in filename:指定要加密的文件存放路径
-out filename:指定加密后的文件存放路径
-salt:自动插入一个随机数作为文件内容加密,默认选项 加点盐:)
-e:加密;
-d:解密,解密时也可以指定算法,若不指定则使用默认算法,但一定要与加密时的算法一致
-a/-base64:当进行加解密时,他只对数据进行运算,有时需要进行base64转换,设置
此选项后加密结果进行base64编码,解密前先进行base64编码。
加密解密算法可以通过自己制定,有什么算法可以通过openssl help enc去查看加密内容。
enc命令:
帮助: man enc

4.5 AES加密操作

  • 在本地文件夹创建一个txt文件,name:1.txt。内容:测试同学
    在这里插入图片描述

  • 执行加密命令,按照提示,输入密码以及确认密码(1234567812345678)。

openssl enc -e -aes-128-ecb -a -salt -in 1.txt -out 2.cipher

在这里插入图片描述
会在此目录下生成2.cipher文件。存储的是加密后的密文
在这里插入图片描述

4.6 AES解密操作

  • 执行加密命令,按照提示,输入密码(1234567812345678)。
openssl enc -d -aes-128-ecb -a -salt -in 2.cipher -out 3.txt

在这里插入图片描述- 查看此目录下生成了一个txt文档,name:3.txt。查看此文件,解密后的原文:测试同学
在这里插入图片描述

4.7 MD5加密

  • 单向加密
openssl dgst
常用选项有:
[-md5|-md4|-md2|-sha1|-sha|-mdc2|-ripemd160|-dss1] :指定一种摘要算法
-out filename:将摘要的内容保存到指定文件中
dgst命令:
帮助: man dgst
openssl dgst -md5 [-hex默认16进制] /PATH/SOMEFILE
openssl dgst -md5 testfile
md5sum /PATH/TO/SOMEFILE
MAC: Message Authentication Code,单向加密的一种延伸应用,用于实现网络通
信中保证所传输数据的完整性机制
CBC-MAC
HMAC:使用md5或sha1算法
  • 对上面1.txt中的测试同学,进行MD5加密。
openssl dgst -md5 1.txt

在这里插入图片描述

4.8 生成密码和Base64

openssl passwd [-crypt] [-1] [-apr1] [-salt string] [-in file] [-stdin] [-
noverify] [-quiet] [-table] {password}
常用选项有:
-1:使用md5加密算法
-salt string:加入随机数,最多8位随机数
-in file:对输入的文件内容进行加密
-stdion:对标准输入的内容进行加密
  • 执行命令
openssl passwd -1 -in 1.txt -salt 12345

在这里插入图片描述

4.9 生成随机数

生成随机数需要用到的标准命令为 rand ,用法如下:
openssl rand [-out file] [-rand file(s)] [-base64] [-hex] num
常用选项有:
-out file:将生成的随机数保存至指定文件中
-base64:使用base64 编码格式
-hex:使用16进制编码格式
  • 执行命令:
openssl rand -hex 123
openssl rand -base64 123

在这里插入图片描述

4.10 生成密钥对

注:首先需要先使用 genrsa 标准命令生成私钥,然后再使用 rsa 标准命令从私钥中提取公钥

genrsa 用法如下(generation rsa的简写):

openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [-f4] [-3]
[-rand file(s)] [-engine id] [numbits]
常用选项:
-out filename:将生成的私钥保存至指定的文件中
-des|-des3|-idea:不同的加密算法
numbits:指定生成私钥的大小,默认是2048

ras用法如下:

openssl rsa [-inform PEM|NET|DER] [-outform PEM|NET|DER] [-in filename] [-passin
arg] [-out filename] [-passout arg]
[-sgckey] [-des] [-des3] [-idea] [-text] [-noout] [-modulus] [-check] [-
pubin] [-pubout] [-engine id]
常用选项:
-in filename:指明私钥文件
-out filename:指明将提取出的公钥保存至指定文件中
-pubout:根据私钥提取出公钥
  • 使用genrsa生成私钥
openssl genrsa -out privatekey.txt 4096

在这里插入图片描述在这里插入图片描述

  • 根据私钥,使用rsa提取出公钥
openssl rsa -in privatekey.txt -out publickey.pub -pubout

在这里插入图片描述在这里插入图片描述

4.11 使用生成的密钥对进行非对称RSA加密

  • 利用4.10生成的公钥加密文件,在目录下创建一个111.txt,内容:测试同学
  • 执行以下命令
openssl pkeyutl -encrypt -in 111.txt -inkey publickey.pub -pubin -out 111.en

注:-in指定要加密的文件,-inkey指定密钥,-pubin表明是用纯公钥文件加密,-out为加密后的文件。

在这里插入图片描述在这里插入图片描述

  • 解密文件,执行以下命令。解密后的文件可以看到依旧是 ”测试同学” 。
openssl pkeyutl -decrypt -in 111.en -inkey privatekey.txt -out 111.de

注:-in指定被加密的文件,-inkey指定私钥文件,-out为解密后的文件。

在这里插入图片描述
在这里插入图片描述

5、什么是数字签名?

  • 数字签名是指将摘要信息使用接收者的公钥进行加密,与密文一起发送给接收者。接收者使用自己的私钥对摘要信息进行解密,然后使用Hash函数对收到的密文产生一个摘要信息,然后将摘要信息与发送者传输过来解密后的摘要信息对比是否一致。如果一致,则表明数据信息没有被篡改。

  • 也就是说,数字签名能够验证收到的信息的完整性,避免中途信息被劫持篡改或丢失。对方可以根据数字签名来判断获取到的数据信息时候是最原始的数据。
    改:

  • 数字签名其实就是明文数据加密之后得到的一个密文,只不过它是用私钥加密生成的而已,我们一般会把数字签名拼接在明文数据后面一起传递给接收方,接收方收到后用公钥解密数字签名,从而验证发送方的身份、以及明文数据是否被篡改。数字签名的生成过程其实就是一个加密过程,数字签名的验签过程就是一个解密过程。

  • 例如,发送一段文字”abcd”,通过Hash算法(方便测试,拟比HashCode)得到hashCode值2987074,然后将2987074再次使用对方的公钥进行加密生成摘要信息,然后将文字”abcd”使用对方的公钥进行加密得到密文,一起发送给接收者。接收者获取到信息后,先通过自己的私钥将摘要信息解密,然后将密文解密,并且通过相同的hash算法计算出密文的hashcode值,对比两个hashcode值是否一致。

  • 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将其中的一把作为公用密钥向其它方公开;得到该公用密钥的乙方使用该密钥对机密信息进行加密后再发送给甲方;甲方再用自己保存的另一把专用密钥(私钥)对加密后的信息进行解密。

6、什么是数字证书?

  • 数字证书有点类似于我们的居民身份证,只是数字证书是基于互联网通信的,用于标记通信双方身份的一种方式。数字证书是由权威机构Certificate Authority发行的,又称之为证书授权,简称为:CA。人们在网上可以根据它来识别对方身份信息。
  • 数字证书绑定了公钥及其持有者的真实身份,它类似于现实生活中的居民身份证,所不同的是数字证书不再是纸质的证照,而是一段含有证书持有者身份信息并经过认证中心审核签发的电子数据,广泛用在电子商务和移动互联网中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Summer@123

不积跬步无以至千里,感谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值