为了确保数据的安全性,建议随机生成一个密钥文件,并将其保存在一个安全的位置,例如 U 盘等。不同于密码,密钥文件不是一个容易记忆的字符串,而是一个文件。只需在解密时使用该文件,就可以避免因密码遗忘而导致无法解密的情况。同时,只有持有该密钥文件的人才能进行解密。因此,务必妥善保管您的密钥文件,防止泄露或丢失。
import random
import uuid
# 生成一个 UUID 作为文件名
file_name = str(uuid.uuid4()).upper()
# 生成 8 个随机的 6 位数,用连字符 - 连接
key = '-'.join(['{:06d}'.format(random.randint(0, 999999)) for _ in range(8)])
# 写入文件
with open(file_name + '.txt', 'w') as f:
f.write(key)
RSA算法中,私钥是解密和签名等关键操作的重要组成部分。为了防止私钥被未经授权的人获取,可以为私钥添加密码。只有知道密码的人才能使用该私钥进行操作,即使私钥被窃取,攻击者也无法直接使用私钥,除非他们能够破解密码。因此,向RSA私钥添加密码是一种有效的加强私钥安全性的措施。
import hashlib
import tkinter as tk
from tkinter import filedialog
def get_rsa_private_key_password() -> bytes:
root = tk.Tk()
file_path = filedialog.askopenfilename(
initialdir="./",
title="Select a File",
filetypes=(("Text files", "*.txt"), ("All files", "*.*")),
)
root.destroy()
if not file_path:
print("No file selected")
return ''.encode()
with open(file_path, "rb") as f:
data = f.read()
hash_value = hashlib.sha256(data).hexdigest()
# hash_value = hashlib.file_digest(f, "sha256") # for python 3.11+
# 获取哈希值并打印输出
rsa_private_key_password = hash_value.encode()
return rsa_private_key_password
password = get_rsa_private_key_password()
password
b'ca9d68c57a9c015fbb8137474a7e8e252d2f8e59e7dd1d5e5da6ebb6598153ee'
RSA密钥对包括公钥和私钥,用于RSA加密算法进行加密和解密操作。公钥可以公开,任何人都可以使用它来加密数据;私钥则是保密的,只有私钥的持有者才能使用它来解密数据。RSA密钥对的安全性取决于私钥的保护程度。如果私钥被泄露,攻击者可以使用它来解密被加密的数据。因此,RSA密钥对的私钥应该被妥善保护,只有授权的人员可以使用它。
Public exponent(公共指数)
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
import datetime
today = datetime.datetime.today().strftime('%Y%m%d')
# 生成RSA密钥对
private_key = rsa.generate_private_key(
public_exponent=65537, key_size=2048 # 公共指数 # 密钥长度
)
# 将私钥对象序列化为 PEM 格式的字符串,并使用密码加密私钥
private_key_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM, # 指定编码格式为 PEM
format=serialization.PrivateFormat.PKCS8, # 指定私钥格式为 PKCS8
encryption_algorithm=serialization.BestAvailableEncryption(password), # 指定加密算法为密码加密
)
# 保存私钥为PEM文件
with open(f"rsa_private_{today}.pem", "wb") as f:
f.write(private_key_pem)
# 从已有的私钥生成公钥,并将公钥对象序列化为 PEM 格式的字符串
public_key = private_key.public_key()
public_key_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
# 保存公钥为 PEM 文件
with open(f"rsa_public_{today}.pem", "wb") as f:
f.write(public_key_pem)
# 打印密钥
print("私钥:\n" + private_key_pem.decode())
print("公钥:\n" + public_key_pem.decode())
私钥:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIEJyEk+yT/I0CAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDFBmhbsRGR9WjxDfySRix/BIIE
0GNZdAPm2MgQmofs1DGemfGc/OUQ1KmTSSTjzqXcyWaFdLrKoFFh9F74QoCukl74
fbXuHG+EcqUxeP3svI479+A4khRD+633sUicdbysTitxVFOpSyQ1MmC/YTQ9hRs4
3rtsjFXXcbO92C2GSOF1UMTUCmWzVjkQE5E2KCD76OZihedyQhWTwvBT2oHxob6G
H7/e+kXhtvbbEsYtAbk9r4SqWXCBzwtEN1otRXYMI3Z1k/VVR7nT6/MUCsFe9go9
vomihRsFFfne9qSosHc4j6AOBVVNkktFN57odEm3QMnrnvlneU0HkX9IoTFn2pCe
vzwndzXuUsiEEMm66AqtdYE+ZlrehuQuFzKqVLEoHGc+lnluFgksBSiE7hF5PKgq
/+QWtFWggThn5ewG/vgobViws+i2QTeoSwkg3z16NeKsU+4H2K5p9AY2X8IofmTu
sYX86v8TNdd6zphaxz4ae6oGHROdyo8It12KM79BHktPQqWBAwzMEv6nQqd6xLAt
7Vt8UHUFTHJOGROu/MvK7dDkzZXsC86U4/LQbx5vE43yF/+cMQcidt3veRGsJHs6
OKRX4IyqQWBCh5lOGH/LD7wXRlzpVSADY4vzHAGaLOemCT0f42loe6+107ijV3FC
khJPX9MDcTvU11TjaNkjcAKXNUwsfHQV+fQGLgQZg05iIB6YdU4bS2WK+B9KhnXN
T/Nui3eBFpJdS6Jn+tntws6RgqxvWBlk2v5vmOmj817KwLkz9DOiuhJkw0GgCzls
Qwa+DRiVsER1d3UjX5DL/UmQpz+rW+aBkSuIq4rDu9x+1O3HzjXv8fFNBhXhaP7D
GFH8fEyqj6pfdYQ1jM8A009UrrQccdqaCLukwJ3JHl1TwN446I+C1Jya629gYumQ
4i72macA8+gCUb94GLgzwG9pKIjoV2dX0qex+Qfzr+gMwOIB8z46eCSl1G7Z67tX
nmIDGjZLH+xTT2cMQZxb5JHkW7l2qIfvIzF7dZR27oBZ32WBqoaw5ou3nat7lOVA
eOFKjgpue35EiSJaqkNyJ525uvLIKVLWyCOwfOcCJFSI1p1cBwyCSdhebdwTmFZ1
pZJR+V0e3QAL5CuwW5iR/hppP9w8NbNBMfFoOvJ/gDu7GGw26xkoYGW2BKBqDDGo
gjhx5jhqMENdPkAVg+3RAG/YlvCP6lqv6SKZsBibqk0R9nA+9t0ynYJPLgK18F54
b+E+Mj/o9W+Qcu4oN9wMRMCY4mWCPla0uoRPNtJCXsb/RK34tHXFbwyyE3+NiXcK
Tsrfp1lzDdL9yHO2c+wqj5cJA42Y/lHNVmex6N6XpqX4quK97GZqjalXlEUbYiHo
SnJrsEX7DrctDD6yAslZ1r7AwqLj2fNdjNIblmjSbY41X1jOJKvmsNOGKF4+sewR
F+Oe8UTAiVKY3fWblNvNRjRACyzZeeMBluCGID3cK2em4pfBsNhQXjBuiP4nbbu1
meTMaNZ7zB+zEia0YpsdBMKFOHLtyBQrLhyF7vPKTHb/tDCBjWhDW7djqb4i414m
ROM0BnX3LxZFvY18L15JtlV+YVe/SYTm1pLaa+mAETNoKPke75joOqJxwod6S6KI
jcgceXmjwveiE45lIrMcGlwOCQJ9YKAa417EjLNr12yf
-----END ENCRYPTED PRIVATE KEY-----
公钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6+6OY0J3HyVK5UjOUB9H
atBLz11LUlN5FUc8aABfRaI50j7xOX5gE2FcWf+/8MbG/c6jToXYgH5FIjK3qi8U
Usnrjo0q4kWeETPo7I1Ndg/GJI/IfExfU0QW6/9cdYYNSaD1wWm2VXHhBZk2F7/A
IiXgyIur8aDbEr342bc7HFACWGQN1FNrcssZHdx4Tk2W/DJZBIy+k7Agn3EXmkOn
bHVrsjDD/pUu2Q/sLjqzfwUnuAdQsyKV/x1JPlfrce1w47Zt8DeSt8Zjy7/eln9d
z3kpdoaj/44HnI6NXN2lqsfKzhLLc/zKljRgX76CYOo64YwwD8aDSXcNM5lZaroz
UwIDAQAB
-----END PUBLIC KEY-----
RSA算法使用随机数生成器进行加密,导致每次加密的结果都不同,增加了破解的难度。但只要使用正确的私钥进行解密,无论加密结果是否相同,都可以将密文还原成相同的明文。RSA算法的安全性依赖于私钥保密和加密算法复杂度,而不是加密结果是否相同。
import base64
message = "Hello, world!"
message_encrypted = public_key.encrypt(
message.encode(),
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
message_encrypted_str = base64.b64encode(message_encrypted).decode()
print(f"原始文本:\n{message}\n")
print(f"加密后的密文(Base64编码):\n{message_encrypted_str}")
原始文本:
Hello, world!
加密后的密文(Base64编码):
znaI16viQLfItYwyIDPcELQirKRiWaNAPw0xp6f3cPkAvUAH1kaJio+ps7MaFPH+1Eqy3K26EmaiKbDvCUuBFOU0iy//VunnvTc125hm2py38aN5BOrA/ZZhSomNV9CVfnzVWjMsJtv/HHqBd6q2wbJrrFFEJDux+bUcg7cCGCnTYuB5799eDAbXavUUXaV5J1yfqnRs1tvTJVLOQBwQdQqZNf9O64sKFVW0JvXNYKJDdSvKHie8FjjLWQbO1wG4L44lNspTjgmMWIWWnVC5RH4WwMcIRrfhOxeUSFd4zI3lztvPQbukUOnsWrJ18ZPqekvXeFjVRZDJoMyKcZ00TQ==
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.backends import default_backend
# 从文件中获取 PEM 格式的字符串
with open('rsa_private_20230719.pem', 'rb') as f:
private_key_pem = f.read()
password = get_rsa_private_key_password()
# 从 PEM 格式的字符串中加载加密的私钥
private_key = serialization.load_pem_private_key(
private_key_pem, password=password, backend=default_backend()
)
message_encrypted = base64.b64decode(message_encrypted_str.encode())
# 使用私钥进行加解密
message_decrypted = private_key.decrypt(
message_encrypted,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
print(f"解密后的明文:\n{message_decrypted.decode()}")
解密后的明文:
Hello, world!
What is RSA encryption, and how does it work?