加密、解密、签名、验签、数字证书、CA浅析

2024-04-23 20:44

本文主要是介绍加密、解密、签名、验签、数字证书、CA浅析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、加密和解密

加密和解密应用的很广,主要作用就是防止数据或者明文被泄露。

加解密算法主要有两大类,对称加密和非对称加密。对称加密就是加密和解密的密钥都是一个,典型的有AES算法。非对称加密就是有公钥和私钥,公钥可以发布出去,私钥只对自己可见,私钥的拥有者需要对通过公钥加密的数据或者信息通过私钥进行解密,这样保证数据不被泄露,典型的非对称加密算法是RSA。下面通过代码实现一下上述过程

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import binascii# 生成密钥对
key = RSA.generate(2048)
private_key = key.export_key()
file_out = open("private.pem", "wb")
file_out.write(private_key)
file_out.close()public_key = key.publickey().export_key()
file_out = open("public.pem", "wb")
file_out.write(public_key)
file_out.close()# 加载密钥
private_key = RSA.import_key(open("private.pem").read())
public_key = RSA.import_key(open("public.pem").read())# 加密数据
message = "Hello, World!"
cipher_rsa = PKCS1_OAEP.new(public_key)
encrypted_message = cipher_rsa.encrypt(message.encode())# 解密数据
decipher_rsa = PKCS1_OAEP.new(private_key)
decrypted_message = decipher_rsa.decrypt(encrypted_message).decode()print("Original Message: ", message)
print("Encrypted Message: ", binascii.b2a_hex(encrypted_message))
print("Decrypted Message: ", decrypted_message)

运行结果如下

二、加密和解密存在的问题

在上述加密数据的代码后面添加两行代码

message = "Hello, World!"
cipher_rsa = PKCS1_OAEP.new(public_key)
encrypted_message = cipher_rsa.encrypt(message.encode())tmp = "Hello, Python!"
encrypted_message = cipher_rsa.encrypt(tmp.encode())

再次运行后,输出如下

可见,解密后的数据发生了变化。

所以,只对数据加解密只能保证数据不被泄露,但是无法保证数据不被修改,就比如上述代码中的message,一旦被截获,就可以对原先数据的密文进行替换,虽然明文被加密的很好,但是最终得到的明文数据也出错

三、摘要、签名、签名验证

摘要、签名和签名验证就是为了解决加解密存在的问题

摘要就是通过特定的算法对一段数据进行概括,摘要算法有SHA(security hash algorithm),MD5(Message-Digest Algorithm),CRC(Cyclic Redundancy Check)等等。摘要算法的特点有三个:1、快。2、同样数据的摘要一样。3、无法通过摘要逆向得出原始数据

签名和签名验证也需要公钥和私钥。签名就是先对明文数据进行摘要计算,然后使用发送方的私钥对摘要进行加密,之后使用接收方的公钥对明文数据进行加密。最后将加密的摘要和加密的内容一起发出。

签名验证就是通过发送方的公钥对加密的摘要进行解密,得到明文数据的摘要,再通过接收方的私钥对明文数据进行解密,对解密后的明文再进行摘要计算,得到另一个明文数据的摘要,两个摘要做对比,一致,表示数据没被修改,否则表示数据被修改。

通过加密和签名可以保证数据既不被泄露,也不会被修改

下面通过代码实现一下上述过程(使用RSA2048对数据进行加解密,RSA4096对数据进行签名和验签)

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
import binascii# 生成加解密密钥对
key = RSA.generate(2048)
private_key2048 = key.export_key()
file_out = open("private2048.pem", "wb")
file_out.write(private_key2048)
file_out.close()public_key2048 = key.publickey().export_key()
file_out = open("public2048.pem", "wb")
file_out.write(public_key2048)
file_out.close()# 生成签名验签密钥对
key2 = RSA.generate(4096)
private_key4096 = key2.export_key()
file_out = open("private4096.pem", "wb")
file_out.write(private_key4096)
file_out.close()public_key4096 = key2.publickey().export_key()
file_out = open("public4096.pem", "wb")
file_out.write(public_key4096)
file_out.close()# 加载密钥
private_key2048 = RSA.import_key(open("private2048.pem").read())
public_key2048 = RSA.import_key(open("public2048.pem").read())private_key4096 = RSA.import_key(open("private4096.pem").read())
public_key4096 = RSA.import_key(open("public4096.pem").read())# 创建一个用于签名验签的对象
signer = PKCS1_v1_5.new(private_key4096)
verifier = PKCS1_v1_5.new(public_key4096)# 加密数据
message = b"Hello, World!"
cipher_rsa = PKCS1_OAEP.new(public_key2048)
encrypted_message = cipher_rsa.encrypt(message)# 计算摘要并签名
hash_object = SHA256.new()
hash_object.update(message)
print(hash_object.hexdigest())
signature = signer.sign(hash_object)# tmp = b"Hello, Python!"
# encrypted_message = cipher_rsa.encrypt(tmp)# 解密数据
decipher_rsa = PKCS1_OAEP.new(private_key2048)
decrypted_message = decipher_rsa.decrypt(encrypted_message).decode()print("Original Message: ", message)
print("Encrypted Message: ", binascii.b2a_hex(encrypted_message))
print("Decrypted Message: ", decrypted_message)# 计算明文摘要
hash_object2 = SHA256.new()
hash_object2.update(decrypted_message.encode())print(hash_object2.hexdigest())# 数据完整性检验,签名验证
try:flag = verifier.verify(hash_object2, signature)if not flag: print(flag, "verification not ok")else:print(flag, "verification ok")
except ValueError:print("signature is not vaild")

运行结果如下

如果对明文数据进行修改,将下面两行代码注释解除

# tmp = b"Hello, Python!"
# encrypted_message = cipher_rsa.encrypt(tmp)

输入如下

可见,加了签名和签名校验后,即使数据被篡改,也能检查出来。这样,就弥补了只有加密算法的而产生的缺陷

四、数字证书和CA

上述的加解密和签名验签都基于一个假设:就是数据的接收方和发送发所持有的公钥都是正确的。但是,公钥也是数据,在收发公钥的过程中,公钥也可以被修改,为了防止公钥数据被篡改,就引入了一个第三方:CA(证书颁发机构(Certificate Authority))。数据的收发双方都从CA获取证书,从证书中提取公钥,保证公钥的正确性。

在嵌入式开发中,虽然没有第三方CA,但是也有类似的机制,把公钥的摘要存储在一块只能写入一次的区域,在程序执行时,计算公钥的哈希,与事先存储的摘要做对比,摘要一致,公钥正确,否则,公钥不正确。这样可以起到一个第三方发布公钥的作用

参考

签名、加密、证书的基本原理和理解 - 知乎

加密、摘要、签名、证书,一次说明白! - 掘金

这篇关于加密、解密、签名、验签、数字证书、CA浅析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/929840

相关文章

SpringBoot3使用Jasypt实现加密配置文件

《SpringBoot3使用Jasypt实现加密配置文件》这篇文章主要为大家详细介绍了SpringBoot3如何使用Jasypt实现加密配置文件功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编... 目录一. 使用步骤1. 添加依赖2.配置加密密码3. 加密敏感信息4. 将加密信息存储到配置文件中5

SpringBoot整合jasypt实现重要数据加密

《SpringBoot整合jasypt实现重要数据加密》Jasypt是一个专注于简化Java加密操作的开源工具,:本文主要介绍详细介绍了如何使用jasypt实现重要数据加密,感兴趣的小伙伴可... 目录jasypt简介 jasypt的优点SpringBoot使用jasypt创建mapper接口配置文件加密

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Java实现MD5加密的四种方式

《Java实现MD5加密的四种方式》MD5是一种广泛使用的哈希算法,其输出结果是一个128位的二进制数,通常以32位十六进制数的形式表示,MD5的底层实现涉及多个复杂的步骤和算法,本文给大家介绍了Ja... 目录MD5介绍Java 中实现 MD5 加密方式方法一:使用 MessageDigest方法二:使用

浅析Python中的绝对导入与相对导入

《浅析Python中的绝对导入与相对导入》这篇文章主要为大家详细介绍了Python中的绝对导入与相对导入的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1 Imports快速介绍2 import语句的语法2.1 基本使用2.2 导入声明的样式3 绝对import和相对i

nginx生成自签名SSL证书配置HTTPS的实现

《nginx生成自签名SSL证书配置HTTPS的实现》本文主要介绍在Nginx中生成自签名SSL证书并配置HTTPS,包括安装Nginx、创建证书、配置证书以及测试访问,具有一定的参考价值,感兴趣的可... 目录一、安装nginx二、创建证书三、配置证书并验证四、测试一、安装nginxnginx必须有"-

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的