Python、JS摘要&加密算法

发布于:2025-02-10 ⋅ 阅读:(62) ⋅ 点赞:(0)

摘要加密

摘要加密,通常指的是使用哈希算法(如MD5、SHA-1、SHA-256等)对原始数据进行处理,生成一个固定长度的哈希值(或称为摘要、指纹)的过程。这个哈希值用于确保数据的完整性和一致性。

一、哈希算法概述

MD5:

输出长度:128位(16字节)
特性:早期哈希算法,速度快但安全性相对较低,存在哈希碰撞和漏洞。

SHA-1:

输出长度:160位(20字节)
特性:相对于MD5更加安全,但仍然存在哈希碰撞的问题,目前已不再被认为足够安全。

SHA-256:

输出长度:256位(32字节)
特性:相对于MD5和SHA-1更加安全,被广泛应用于需要高度安全性的场景,如比特币等。

二、识别加密后的字符串

长度判断:

由于MD5、SHA-1和SHA-256的输出长度不同,因此可以通过字符串的长度来初步判断其所属的哈希算法。
32位十六进制数(16字节×2=32字符):可能是MD5。
40位十六进制数(20字节×2=40字符):可能是SHA-1。
64位十六进制数(32字节×2=64字符):可能是SHA-256。

格式判断:

哈希值通常以十六进制字符串的形式表示。因此,可以检查字符串是否仅包含十六进制字符(0-9和a-f,小写或大写)。
在线工具或库:
使用在线哈希算法识别工具或编程库中的函数来验证字符串是否匹配特定哈希算法的格式和特性。
例如,可以编写一个简单的程序或使用在线服务来尝试将字符串作为不同哈希算法的输入进行验证,看哪个算法能够生成匹配的哈希值。

from hashlib import md5

md5_obj=md5()
md5_obj.update('123456'.encode())
res=md5_obj.hexdigest()
print(res)


==========输出结果========
e10adc3949ba59abbe56e057f20f883e

对称加密

对称加密,简而言之,就是使用相同的密钥进行加密和解密的过程。

AES加密

AES(Advanced Encryption Standard,高级加密标准)是一种广泛使用的对称加密算法,支持128位(16字节)、192位(24字节)和256位(32字节)三种密钥长度。加密数据的长度必须是16字节的倍数,因此可能需要进行填充。加密后的数据通常以二进制形式存在,但为了便于网络传输和存储,可以将其转换为16进制或更紧凑的base64编码格式。

AES加密实现

下载第三方库

pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad

# AES主要分为两种加密模式,CBC需要传入16位的iv,ECB只要key即可 key的长度必须是16、24、32位,加密数据的长度也必须是16的倍数
key='1234567891234567'.encode()
data="123456723123456222\r".encode()
aes=AES.new(key=key,mode=AES.MODE_ECB,)

# 加密数据的长度必须是16的倍数,需要进行相关处理
res_data=pad(data,16)
print(res_data)
res=aes.encrypt(res_data)
print("加密后:",base64.b64encode(res).decode())

=================================
加密后: eMe4RX4yU5RBIbJLE/EGyEZ7QAqZcF3U+ojRRok6ZvA=


AES解密实现

import base64

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad

# AES主要分为两种加密模式,CBC需要传入16位的iv,ECB只要key即可 key的长度必须是16、24、32位,加密数据的长度也必须是16的倍数
key='1234567891234567'.encode()
data="123456723123456222\r".encode()
aes=AES.new(key=key,mode=AES.MODE_ECB)

res_decrypt=aes.decrypt(res)
print("解密:",unpad(res_decrypt,16).decode())

============
解密后: 123456723123456222

非对称加密

非对称加密是一种使用公钥和私钥对进行加密和解密的技术。以下是对非对称加密中公钥加密私钥解密(数据加密)和私钥加密公钥解密(数据签名)的简略补全信息回答:

公钥加密私钥解密(数据加密)

过程:发送方使用接收方的公钥对消息进行加密,然后将密文发送给接收方。接收方收到密文后,使用自己的私钥进行解密,得到原始的消息。
特点:

公钥可以公开,任何人都可以使用它来加密消息,但只有私钥的持有者才能将其解密。
安全性高,因为攻击者无法从公钥中推断出私钥。
公钥分发方便,无需像对称加密一样需要通过安全渠道传输密钥。

私钥加密公钥解密(数据签名)

过程:发送方使用自己的私钥对消息进行签名,然后将签名和消息一起发送给接收方。接收方收到消息和签名后,使用发送方的公钥验证签名,以确认消息的真实性和完整性。
特点:

私钥加密的过程实际上是对消息摘要的加密,因为直接使用私钥对整个消息进行加密在效率和安全性上都不现实。
公钥解密的过程是验证签名的过程,通过比较解密后的摘要与消息生成的摘要是否一致来确认消息的真实性。
数据签名可以保证消息的完整性和真实性,防止消息在传输过程中被篡改或伪造。
非对称加密在数据安全领域具有广泛的应用,如HTTPS、数字签名、电子邮件加密等。它解决了对称加密中密钥分发和管理的问题,提供了更高的安全性和灵活性。同时,非对称加密也需要注意密钥的安全管理,避免私钥泄露和公钥被替换等安全风险。

python 实现

import base64

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
import os


# 生成 RSA 密钥对
def generate_keys():
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    public_key = private_key.public_key()
    return private_key, public_key


# 保存私钥到文件
def save_private_key(private_key, file_path):
    with open(file_path, "wb") as f:
        f.write(
            private_key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.PKCS8,
                encryption_algorithm=serialization.NoEncryption()
            )
        )


# 保存公钥到文件
def save_public_key(public_key, file_path):
    with open(file_path, "wb") as f:
        f.write(
            public_key.public_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PublicFormat.SubjectPublicKeyInfo
            )
        )


# 从文件加载私钥
def load_private_key(file_path):
    with open(file_path, "rb") as f:
        private_key = serialization.load_pem_private_key(
            f.read(),
            password=None,
            backend=default_backend()
        )
    return private_key


# 从文件加载公钥
def load_public_key(file_path):
    with open(file_path, "rb") as f:
        public_key = serialization.load_pem_public_key(
            f.read(),
            backend=default_backend()
        )
    return public_key


# 使用公钥加密数据
def encrypt_message(public_key, message):
    ciphertext = public_key.encrypt(
        message,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )
    return ciphertext


# 使用私钥解密数据
def decrypt_message(private_key, ciphertext):
    ciphertext = base64.b64decode(ciphertext)
    plaintext = private_key.decrypt(
        ciphertext,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )
    return plaintext


# 示例使用
if __name__ == "__main__":
    # 生成密钥对
    private_key, public_key = generate_keys()

    # 保存密钥到文件
    save_private_key(private_key, "private_key.pem")
    save_public_key(public_key, "public_key.pem")

    # 加载密钥
    loaded_private_key = load_private_key("private_key.pem")
    loaded_public_key = load_public_key("public_key.pem")

    # 要加密的消息
    message = b"Hello, this is a secret message!"

    # 加密消息
    ciphertext = encrypt_message(loaded_public_key, message)
    base64_ciphertext = base64.b64encode(ciphertext).decode()
    print(f"Ciphertext: {base64_ciphertext}")

    # 解密消息
    decrypted_message = decrypt_message(loaded_private_key, base64_ciphertext)
    print(f"Decrypted message: {decrypted_message.decode()}")

模拟浏览器环境实现

npm下载:

npm install crypto-js

MD5

const CryptoJS = require('crypto-js');
CryptoJS.MD5(n).toString(CryptoJS.enc.Hex);

AES解密

const CryptoJS = require('crypto-js');
 // 从对象 r 中获取密钥和初始化向量
    const key = CryptoJS.enc.Utf8.parse('EB444973714E4A40876CE66BE45D5930');
    const iv = CryptoJS.enc.Utf8.parse('B5A8904209931867');

    // CryptoJS 期望的 ciphertext 是 Base64 或 CipherParams 格式
    // 如果你的 ciphertext 是十六进制字符串,你需要先将其转换为 CipherParams 格式
    // 这里假设 ciphertext 是 Base64 编码的,或者你可以根据需要进行转换
    const encrypted = CryptoJS.enc.Base64.parse(ciphertext); // 如果 ciphertext 是 Base64 编码的
    // const encrypted = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Hex.parse(ciphertext) }); // 如果 ciphertext 是十六进制字符串,并使用这种方式转换(注意:这种转换可能不是 CryptoJS 的标准用法,你需要根据实际情况进行调整)

    // 使用 AES-CBC 解密
    const decrypted = CryptoJS.AES.decrypt({ ciphertext: encrypted }, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });

    // 将解密后的数据转换为字符串
    decrypted.toString(CryptoJS.enc.Utf8);

网站公告

今日签到

点亮在社区的每一天
去签到