python PBEWithMD5AndDES 实现

python PBEWithMD5AndDES 实现 , 在网上不好找,使用大模型生成的代码基本上都是错的, 浪费时间验证, 如下是实测有效的, 跟java程序的PBEWithMD5AndDES 实现进行比较, 输出的值是一样的, 设置了VIP可见, 如果你不是VIP, 可以参考源代码自行修改 pbe-with-md5-and-triple-des-python

因为源码有些陈旧会有些问题会报错, 下面我发布的是验证可用的, 使用中遇到啥问题, 欢迎留言.

安装依赖, 实测于版本 python 3.11

pip install pycryptodome

使用方法, 这里面,我将原函数做了修改, 输出是16进制数值, 方便存储

from pbe_with_md5_and_triple_des import PBEWithMD5AndDES, PBEWithMD5AndTripleDESif __name__ == '__main__':password = '123456'plain_text = 'admin'salt = 'RCGTeGiH'.encode("utf-8")cipher = PBEWithMD5AndDES()encrypted_text = cipher.encrypt(plain_text, password, salt)print(encrypted_text)print(cipher.decrypt(encrypted_text, password, salt))

代码如下

    """pbe_with_md5_and_triple_des~~~~~~~~~~~~This module provides ciphers that implement 'PBE With MD5 And Triple DES' and 'PBE With MD5 And DES' algorithms:copyright: (c) 2017 by Anton Koba (anton.koba@gmail.com):license: MIT"""from abc import ABC, abstractmethod
import base64
import hashlib
import array
from Crypto.Cipher import DES, DES3BLOCK_LENGTH_BYTES = 8  # pad incoming message to whole length of blockDERIVED_KEY_ITERATIONS = 1000  # cycles to hash over to produce dk and ivclass AbstractPBEWithMD5AndDES(ABC):""" Defines basic algorithm for PBE With MD5 And DES / Triple DES (DESede)DES and Triple DES versions differ in the way how the derived key (dk) andinitialization vector (iv) are generated"""# use DES3 (triple DES a.k.a. DESede) or plain DEStriple_des = Truedef __init__(self, iterations=1000):super().__init__()self.iterations = iterationsdef encrypt(self, plain_text, password, salt):"""Encrypts plain text with given password:param plain_text: plain text to decrypt:param password: password to decrypt with:return: base64-encoded encrypted text"""# pad message up to a whole block sizepadded_text = self._pad_plain_text(plain_text)# get dk and iv using proper algorithm (either for DES ot DES3), password as bytes(dk, iv) = self._get_derived_key_and_iv(password.encode('utf-8'), salt)# get proper class (DES/DES3) to instantiate and use for encodingdes_class = self._get_des_encoder_class()des = des_class.new(dk, DES.MODE_CBC, iv)# do the encryptionencrypted_text = des.encrypt(padded_text.encode('utf-8'))print(padded_text)print(encrypted_text.hex())# return encrypted text prepended with salt, all base64-encodedreturn base64.b64encode(salt + encrypted_text)def decrypt(self, encoded_text, password):"""Decrypts encoded_text with given password:param encoded_text: encoded string:param password: password to decrypt with:return: decrypted plain text as string (bytes)"""decoded_encrypted_text = base64.b64decode(encoded_text)# get first 8 bytes as saltsalt = decoded_encrypted_text[:8]# get rest of data (starting from 8th byte as messageencrypted_text_message = decoded_encrypted_text[8:]# get dk and iv using proper algorithm (either for DES ot DES3)(dk, iv) = self._get_derived_key_and_iv(password.encode('utf-8'), salt)# get proper class (DES/DES3) to instantiate and use for decodingdes_class = self._get_des_encoder_class()des = des_class.new(dk, DES.MODE_CBC, iv)# do the decryptiondecrypted_text = des.decrypt(encrypted_text_message)# return decrypted text with possible padding removed, converted from bytes string to stringreturn str(self._unpad_decrypted_message(decrypted_text), 'utf-8')def _pad_plain_text(self, plain_text):"""Pads plain text up to the whole length of block (8 bytes).We are adding chars which are equal to the number of padded bytes.i.e. 'hello' -> 'hello/x03/x03/x03':param plain_text: plain text to be padded (bytes):return: padded bytes"""pad_number = BLOCK_LENGTH_BYTES - (len(plain_text) % BLOCK_LENGTH_BYTES)result = plain_textfor i in range(pad_number):result += chr(pad_number)return resultdef _unpad_decrypted_message(self, decrypted_message):""" Decrypted message could be padded on the end, last character means number of:param decrypted_message: with PKCS7 padding:return: unpadded text"""message_length = len(decrypted_message)pad_value = decrypted_message[-1]if pad_value > 8:# no padding usedreturn decrypted_messageelse:# where real data endsposition = message_length - pad_value# padding element, repeated `pad_value` number of times, as byte stringpadding_elements = array.array('B', [pad_value] * pad_value).tostring()# check if correctly paddedif pad_value == 0 or decrypted_message[-pad_value:] != padding_elements:raise ValueError('Incorrect padding')return decrypted_message[:position]def _get_des_encoder_class(self):return DES3 if self.triple_des else DES@abstractmethoddef _get_derived_key_and_iv(self, password, salt, cycles=DERIVED_KEY_ITERATIONS):return Noneclass PBEWithMD5AndDES(AbstractPBEWithMD5AndDES):triple_des = Falsedef _get_derived_key_and_iv(self, password, salt, cycles=DERIVED_KEY_ITERATIONS):"""Returns tuple of dk(8 bytes) and iv(8 bytes) for DESLogic: concatenate password + salt and hash them given number of iterations(result of hash function is given to it an an input on following iteration):param password: password used for encryption/decryption:param salt: salt:param cycles: number of hashing iterations:return: (8 bytes dk, 8 bytes iv)"""key = password + saltfor i in range(cycles):m = hashlib.md5(key)key = m.digest()return key[:8], key[8:]class PBEWithMD5AndTripleDES(AbstractPBEWithMD5AndDES):def _get_derived_key_and_iv(self, password, salt, cycles=DERIVED_KEY_ITERATIONS):"""Returns tuple of dk(24 bytes) and iv(8 bytes) for DES3 (Triple DES, DESede)Logic:Salt will be split in two halves and processed separately.1. If 2 halves of salt are same, reverse first part2. For each half of salt:- Start hashing loop with half of salt + password (not password + salt as in DES keys)concatenate output of hash with password on each iteration- iterate for each half of salt given number of times3. Join two parts of hashes (16 + 16 bytes)4. First 24 bytes will be used as key for DES3, latest 8 bytes - iv for DES3:param password: password used for encryption/decryption:param salt: salt:param cycles: number of hashing iterations (see description):return: (24 bytes dk, 8 bytes iv)"""# reverse first half of salt if two halves are the sameif salt[:4] == salt[4:]:salt = salt[-5::-1] + salt[4:]# do part 1part1_to_hash = salt[:4]for i in range(cycles):m = hashlib.md5(part1_to_hash + password)part1_to_hash = m.digest()# do part 2part2_to_hash = salt[4:]for i in range(cycles):m = hashlib.md5(part2_to_hash + password)part2_to_hash = m.digest()result = part1_to_hash + part2_to_hash# key, ivreturn result[:24], result[24:]if __name__ == '__main__':password = '123456'plain_text = 'admin'salt = 'RCGTeGiH'.encode("utf-8")cipher = PBEWithMD5AndDES()encrypted_text = cipher.encrypt(plain_text, password, salt)print(encrypted_text)dd = cipher.decrypt(encrypted_text,password)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3748.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode 二叉树中的最大路径和

算法思想 这道题要求在一棵二叉树中找到路径和最大的路径。路径可以从树中任意一个节点开始,到任意一个节点结束,但路径上的节点必须是连续的。 算法使用递归的方式来遍历树中的每个节点,并在遍历过程中计算包含当前节点的最大路径和。具体…

《2024中国城市音乐产业发展指数报告》重磅发布

11月4日,《2024中国城市音乐产业发展指数研究报告》(以下简称“报告”)在成都首次公开发布。该报告由中国音像与数字出版协会音乐产业促进工作委员会指导编制,道略产业研究院、四川音乐学院孙洪斌教授团队深度参与。 该指数评价对象涵盖直辖市、副省级城市和省会城市等共36个城…

解锁金融未来,Python带你玩转大数据!

厌倦了复杂的金融报表,想用数据驱动投资决策,却不知从何下手? 别担心! 《Python金融大数据分析快速入门与案例详解》带你轻松入门,掌握数据分析利器,成为金融领域的弄潮儿! 为什么选择这本书&…

STM32 + CubeMX + 硬件SPI + W5500 +TcpClient

这篇文章记录一下STM32W5500TCP_Client的调试过程,实现TCP客户端数据的接收与发送。 目录 一、W5500模块介绍二、Stm32CubeMx配置三、Keil代码编写1、添加W5500驱动代码到工程(添加方法不赘述,驱动代码可以在官网找)2、在工程中增…

template advanced

一.仿函数再探 stl_stack/queue-CSDN博客 在priority_queue中,我们介绍了仿函数作为第三个参数来改变堆的类型,而仿函数还有其他的用处。 那么我们是否可以借助优先级队列来对日期类进行排序呢? 答案是可以的,但前提是该日期…

spring源码[spring启动流程]

spring启动流程 AnnotationConfigApplicationContext的构造方法 1.父类构造方法,构造一个DefaultListableBeanFactory 在调用AnnotationConfigApplicationContext的构造方法之前,会调用父类GenericApplicationContext的无参构造方法,会构造…

使用Python做一个微信机器人

使用Python制作微信机器人是一个有趣且实用的项目,它可以让您自动化处理微信消息、监控微信群、甚至实现智能聊天等功能。 请求参数 Header 参数 export interface ApifoxModel {"X-GEWE-TOKEN": string;[property: string]: any; } Body 参数applicat…

Python-创建并调用自定义文件中的模块/函数

背景:在Python编程中,我们常常需要创建自己的专属文件,以便帮助我们更高效,快捷地完成任务。那么在Python中我们怎么创建并调用自己文件中的模块/函数呢? 在Python中调用自定义文件,通常是指调用自己编写的Python模块…

【C++】C++17结构化绑定、std::optional、std::variant、std::any

二十二、C17中的结构化绑定、std::optional、std::variant、std::any 本部分是一个小系列,介绍C17中新引入的、用来解决各种不同返回情况的、标准库新组件。 1、C的结构化绑定 结构化绑定structured bindings是C17中引入的一项特性,它允许开发者方便地…

ntkrnlmp.exe导致蓝屏死机的解决方法

在使用Windows操作系统的过程中,用户可能会遇到由ntkrnlmp.exe文件错误引发的蓝屏死机(Blue Screen of Death, BSOD)问题,这不仅影响了日常的工作效率,也可能造成数据丢失的风险。本文将为您提供一系列即时排查与修复n…

U3D游戏开发之骨骼动画相关

目录 1 作为U3D程序如何制作骨骼动画 2 骨骼动画程序代码相关 这个内容我在很久之前就想写了,很多项目也与骨骼动画挂钩,今天我们揭秘的是2D骨骼动画。来聊一聊大家可能非常关注的两个问题:作为程序如何制作骨骼动画?接到美术的骨…

java:题目:用Java实现简单的自取取款操作

import java.util.Scanner; public class ATM {public static void main(String[] args){//自主取款主类Scanner scnew Scanner(System.in);System.out.println("请输入账户号码:");String BankAccoutsrsc.nextLine();/BankAccout3 newBankAccoutnew Bank…

VLAN 高级技术 ——QinQ的配置

QinQ的概述: QinQ技术是一种扩展虚拟局域网(VLAN)数量空间的技术,通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来实现。以下是对QinQ技术的详细概述: QinQ技术的定义与背景 定义:QinQ&#xff08…

不得不承认供电公司信息宣传向媒体投稿的好方法找到了

初入国网供电公司,我被分配到了信息宣传部门,负责每月的信息宣传投稿任务。这项任务看似简单,实则充满挑战。一开始,我满怀热情,以为只要写出高质量的文章,就能顺利发表。然而,现实给了我当头一棒。传统的邮箱投稿方式,不仅竞争压力大,审核严格,而且周期漫长。每次投稿后,我总是…

『YOLOV5』| 一文搞定训练过程中的意外终止、以及想继续增加训练轮数!

文章目录 情况一:意外训练中断(程序未训练完成,想完成目标训练轮数)情况二:自动训练完成(程序已完成训练,想增加训练轮数) 情况一:意外训练中断(程序未训练完…

GCC编译器的`-Wall`、`-Wextra`和`-pedantic`选项解读

gcc是广泛使用的开源编译器,-Wall、-Wextra和-pedantic是gcc中用于控制警告信息的选项,以下是详细介绍: -Wall(启用大部分警告) 功能:-Wall 选项用于启用一系列常用的警告信息,这些警告能帮助…

MMBench-Video:上海 AI Lab 联合多所高校推出长视频理解基准测试工具,全面评估 LVLMs 视频理解的能力

❤️ 如果你也关注大模型与 AI 的发展现状,且对大模型应用开发非常感兴趣,我会快速跟你分享最新的感兴趣的 AI 应用和热点信息,也会不定期分享自己的想法和开源实例,欢迎关注我哦! 🥦 微信公众号&#xff…

高频电子线路---调角频谱与频宽

目录 调角频谱(FM单频调制) 带宽 调频方法 直接调频方法与电路 变容二极管 如何提升频偏? 1. 增大调制信号的幅度(增大调制深度) 2. 提高调制信号的频率 3. 提高调制深度(调制指数) 4. 增加发射功率 5. 使用特殊的调制…

摘要、数字签名、对称加密、非对称加密综合应用示例以及技术原理说明

图:介绍了数字信封的安全传输过程 关键术语 散列:Hash(哈希),一般翻译做散列、杂凑,是把任意长度的输入(数据信息)通过散列算法变换成固定长度的输出,该输出就是散列值…

java学习3---面向对象

一、设计对象并使用 1.类和对象 类是共同特征的描述;对象是真实存在的具体实例。 2.类的几个补充注意事项 二、封装 对象代表什么,就得封装对应的数据,并提供数据对应的行为。 封装告诉我们如何正确的设计对象 三、this关键字 this可以区…