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

一、加密和解密

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

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

python 复制代码
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)

运行结果如下

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

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

python 复制代码
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对数据进行签名和验签)

python 复制代码
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")

运行结果如下

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

python 复制代码
# tmp = b"Hello, Python!"
# encrypted_message = cipher_rsa.encrypt(tmp)

输入如下

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

四、数字证书和CA

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

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

参考

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

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

相关推荐
黑客Ela22 分钟前
网络安全问题概述
安全·web安全·php
思通数科多模态大模型1 小时前
10大核心应用场景,解锁AI检测系统的智能安全之道
人工智能·深度学习·安全·目标检测·计算机视觉·自然语言处理·数据挖掘
思通数科AI全行业智能NLP系统3 小时前
六大核心应用场景,解锁AI检测系统的智能安全之道
图像处理·人工智能·深度学习·安全·目标检测·计算机视觉·知识图谱
网络安全(king)3 小时前
【Python】【持续项目】Python-安全项目搜集
开发语言·python·安全
go_to_hacker6 小时前
容器安全检测和渗透测试工具
测试工具·安全
澜世6 小时前
2024小迪安全基础入门第二课
网络·笔记·安全
Donvink8 小时前
大模型安全和越狱攻击——《动手学大模型》实践教程第五章
深度学习·安全·语言模型·llama
佚名程序员8 小时前
【Node.js】全面解析 Node.js 安全最佳实践:保护您的应用
安全·node.js
亚信安全官方账号8 小时前
获国家权威机构认可 亚信安全荣获CNVD技术组支撑单位认证
安全