当前位置: 首页 > news >正文

适合翻译做兼职的网站软件培训手册

适合翻译做兼职的网站,软件培训手册,aaa云主机怎么做网站,aqq网站开发本文内容 数据加密概述Python中实现数据加密的模块简介hashlib与hmac模块介绍random与secrets模块介绍base64模块介绍pycrypto模块介绍总结参考文档提示#xff1a; Python 2.7中的str是字节串#xff0c;而Python 3.x中的str是字符串。本文中的代码都是通过Python 2.7实现的… 本文内容 数据加密概述Python中实现数据加密的模块简介hashlib与hmac模块介绍random与secrets模块介绍base64模块介绍pycrypto模块介绍总结参考文档 提示 Python 2.7中的str是字节串而Python 3.x中的str是字符串。本文中的代码都是通过Python 2.7实现的如果你使用的是Python 3.x由于下面大部分加密与解密函数的参数都要求是字节对象因此在调用下面介绍的加解密函数时可能需要先将字符串参数转换为字节对象。 一、数据加密概述 1. 网络数据传输面临的威胁 网络安全涉及很多方面而网络数据的安全传输通常会面临以下几方面的威胁 数据窃听与机密性 即怎样保证数据不会因为被截获或窃听而暴露。数据篡改与完整性 即怎样保证数据不会被恶意篡改。身份冒充与身份验证 即怎样保证数据交互双方的身份没有被冒充。2. 相应的解决方案 针对以上几个问题可以用以下几种数据加密方式来解决每种数据加密方式又有多种不同的算法实现 数据加密方式描述主要解决的问题常用算法对称加密指数据加密和解密使用相同的密钥数据的机密性DES, AES非对称加密也叫公钥加密指数据加密和解密使用不同的密钥--密钥对儿身份验证DSARSA单向加密指只能加密数据而不能解密数据数据的完整性MD5SHA系列算法 需要说明的是上面SHA系列算法是根据生成的密文的长度而命名的各种算法名称如SHA1160bits、SHA224、SHA256、SHA384等。我们常听说的MD5算法生成的密文长度为128bits。 关于上面提到的这些内容大家可以参考《网络数据传输安全及SSH与HTTPS工作原理》这篇博文来了解更多的信息。本文主要讨论的问题是我们如何使用Python来实现这些数据加密方式。 二、Python中实现数据加密的模块简介 Python中的大部分功能都是通过模块提供的因此我们主要是通过Python中提供的一些内置的模块或外部模块来实现上面提到的各种加密算法。使用过程也很简单只需要调用这些模块提供的相应的函数接口即可。 1. Python内置的加密模块演化过程 上面我们已经提到过单向加密算法有MD5、SHA系列算法 和 HMAC而到目前为止Python内置的用于实现数据加密的模块也主要是提供单向加密功能并且这些模块随着Python版本的迭代也经历了一些调整和整合 Python2.5之前的版本所提供的加密模块有md5、sha和hmacPython2.5开始把对md5和sha算法的实现整合到一个新的模块hashlibPython3.x开始去掉了md5和sha模块仅剩下hashlib和hmac模块Python3.6增加了一个新的可以产生用于密钥管理的安全随机数的模块secrets。md5模块和sha模块为什么会被整合到一个hashlib模块中呢 因为md5模块提供的是MD5算法的实现sha模块提供的是SHA1算法的实现而MD5和SHA1都是hash算法具体解释看下面的名词解释。 2. 相关名词解释 HASH 一般翻译为“散列”也有直接音译为“哈希”就是把任意长度的输入又叫做预映射pre-image通过散列算法变成固定长度的输出该输出值就是散列值。这种转换是一种压缩映射也就是散列值的空间通常远小于输入的空间不同的输入可能会散列成相同的输出而不可能从散列值来唯一确认输入值。简单来说hash算法就是一种将任意长度的消息压缩为某一固定长度的消息摘要的函数。 MD5 全称为 Message Digest algorithm 5即信息摘要算法。该算法可以生成定长的数据指纹被广泛应用于加密和解密技术常用于文件和数据的完整性校验。 SHA 全称为 Secure Hash Algorithm即安全散列算法/安全哈希算法。该算法是数字签名等密码学应用中的重要工具被广泛应用于电子商务等信息安全领域。根据生成的密文的长度而命名的各种具体的算法有SHA1160bits、SHA224224bits、SHA256256bits、SHA384384bits等。 HMAC 全称为 Hash Message Authentication Code即散列消息鉴别码。HMAC是基于密钥的哈希算法认证协议主要是利用哈希算法如MD5, SHA1以一个密钥和一个消息作为输入生成一个消息摘要作为输出因此其具体的算法名称为HMAC-MD5、HMAC-SHA1等。可见HMAC算法是基于各种哈希算法的只是它在运算过程中还可以使用一个密钥来增强安全性。 3. 本文要讲解的Python内置模块简介 Python早期的相关模块这里不再介绍了我们今天主要说明的是以下几个模块 模块名内置模块描述hashlibY主要提供了一些常见的单向加密算法如MD5SHA等每种算法都提供了与其同名的函数实现。hmacY提供了hmac算法的实现hamc也是单向加密算法但是它支持设置一个额外的密钥(通常被称为salt)来提高安全性randomY该模块主要用于一些随机操作如获取一个随机数从一个可迭代对象中随机获取指定个数的元素。secretsY这是Python 3.6中新增的模块用于获取安全随机数。base64Y该模块主要用于二进制数据与可打印ASCII字符之间的转换操作它提供了基于Base16, Base32, 和Base64算法以及实际标准Ascii85和Base85的编码和解码函数。pycryptoN支持单向加密、对称加密和公钥加密以及随机数操作这是个第三方模块需要额外安装。 说明 random模块严格上来讲并不能被称为数据加密模块且官方文档中也强调过该模块不应该用于数据加密。但是我们在进行数据加密时还是会常常用到随机数的操作所以这里就顺便对这个模块进行下说明。 三、hashlib与hmac模块介绍 hashlib和hmac都是python内置的加密模块它们都提供实现了单向加密算法的api。 1. hashlib模块 hashlib模块简介 hashlib模块为不同的安全哈希/安全散列Secure Hash Algorithm和 信息摘要算法Message Digest Algorithm实现了一个公共的、通用的接口也可以说是一个统一的入口。因为hashlib模块不仅仅是整合了md5和sha模块的功能还提供了对更多中算法的函数实现如MD5SHA1SHA224SHA256SHA384和SHA512。 提示 “安全哈希/安全散列” 与 “信息摘要” 这两个术语是可以等价互换的。比较老的算法被称为消息摘要而现代属于都是安全哈希/安全散列。 hashlib模块包含的函数与属性 函数名/属性名描述hashlib.new(name[, data])这是一个通用的哈希对象构造函数用于构造指定的哈希算法所对应的哈希对象。其中name参数用于指定哈希算法名称如md5, sha1不区分大小写data是一个可选参数表示初始数据。hashlib.哈希算法名称()这是一个hashlib.new()的替换方式可以直接通过具体的哈希算法名称对应的函数来获取哈希对象如 hashlib.md5()hashlib.sha1()等。hashlib.algorithms_guaranteedPython 3.2新增的属性它的值是一个该模块在所有平台都会支持的哈希算法的名称集合set([sha1, sha224, sha384, sha256, sha512, md5])hashlib.algorithms_availablePython 3.2新增的属性它的值是是一个当前运行的Python解释器中可用的哈希算法的名称集合algorithms_guaranteed将永远是它的子集。hash对象包含的方法与属性 函数名/属性名描述hash.update(data)更新哈希对象所要计算的数据多次调用为累加效果如m.update(a); m.update(b)等价于m.update(ab)hash.digest()返回传递给update()函数的所有数据的摘要信息--二进制格式的字符串hash.hexdigest()返回传递给update()函数的所有数据的摘要信息--十六进制格式的字符串hash.copy()返回该哈希对象的一个copy(clone)这个函数可以用来有效的计算共享一个公共初始子串的数据的摘要信息。hash.digest_sizehash结果的字节大小即hash.digest()方法返回结果的字符串长度。这个属性的值对于一个哈希对象来说是固定的md5:16sha1(20), sha224(28)hash.block_sizehash算法内部块的字节大小hash.name当前hash对象对应的哈希算法的标准名称--小写形式可以直接传递给hashlib.new()函数来创建另外一个同类型的哈希对象。hashlib模块使用步骤 1获取一个哈希算法对应的哈希对象比如名称为hash 可以通过 hashlib.new(哈希算法名称, 初始出入信息)函数来获取这个哈希对象如hashlib.new(MD5, Hello)hashlib.new(SHA1, Hello)等也可以通过hashlib.哈希算法名称()来获取这个哈希对象如hashlib.md5(), hashlib.sha1()等。 2设置/追加输入信息 调用已得到哈希对象的update(输入信息)方法可以设置或追加输入信息多次调用该方法等价于把每次传递的参数凭借后进行作为一个参数垫底给update()方法。也就是说多次调用是累加而不是覆盖。 3获取输入信息对应的摘要 调用已得到的哈希对象的digest()方法或hexdigest()方法即可得到传递给update()方法的字符串参数的摘要信息。digest()方法返回的摘要信息是一个二进制格式的字符串其中可能包含非ASCII字符包括NUL字节该字符串长度可以通过哈希对象的digest_size属性获取而hexdigest()方法返回的摘要信息是一个16进制格式的字符串该字符串中只包含16进制的数字且长度是digest()返回结果长度的2倍这可用邮件的安全交互或其它非二进制的环境中。 hashlib模块使用实例 我们以MD5算法为例获取字符串Hello, World的摘要信息也叫数据指纹 import hashlibhash hashlib.md5() hash.update(Hello, ) hash.update(World!) ret1 hash.digest() print(type(ret1), len(ret1), ret1) ret2 hash.hexdigest() print(type(ret2), len(ret2), ret2) 输出结果 (type str, 16, e\xa8\xe2}\x88y(81\xb6d\xbd\x8b\x7f\n\xd4) (type str, 32, 65a8e27d8879283831b664bd8b7f0ad4) 分析 digest()方法返回的结果是一个二进制格式的字符串字符串中的每个元素是一个字节我们知道1个字节是8bitsMD5算法获取的数据摘要长度是128bits因此最后得到的字符串长度是128/816hexdigest()方法返回的结果是一个16进制格式的字符串字符串中每个元素是一个16进制数字我们知道每个16进制数字占4bitsMD5算法获取的数据摘要长度是128bits因此最后得到的字符串长度是128/432。 在实际工作中我们通常都是获取数据指纹的16进制格式比如我们在数据库中存放用户密码时不是明文存放的而是存放密码的16进制格式的摘要信息。当用户发起登录请求时我们按照相同的哈希算法获取用户发送的密码的摘要信息与数据中存放的与该账号对应的密码摘要信息做比对两者一致则验证成功。 另外需要说明的是下面这几段代码是等价的 hash hashlib.md5() hash.update(Hello, ) hash.update(World!) hash hashlib.md5() hash.update(Hello, World!) hash hashlib.new(md5) hash.update(Hello, World!) hash hashlib.new(md5, Hello, ) hash.update(World!) 说明 如果我们想使用其他哈希算法来获取数据指纹只需要把上面代码中的md5换成其他算法名即可如hashlib.sha1()hashlib.new(sha1)等。 2. hmac模块 hashmac模块简介 前面说过HMAC算法也是一种一种单项加密算法并且它是基于上面各种哈希算法/散列算法的只是它可以在运算过程中使用一个密钥来增增强安全性。hmac模块实现了HAMC算法提供了相应的函数和方法且与hashlib提供的api基本一致。 hmac模块提供的函数 函数名描述hmac.new(key, msgNone, digestmodNone)用于创建一个hmac对象key为密钥msg为初始数据digestmod为所使用的哈希算法默认为hashlib.md5hmac.compare_digest(a, b)比较两个hmac对象返回的是ab的值hmac对象中的方法和属性 方法名/属性名描述HMAC.update(msg)同hashlib.update(msg)HMAC.digest()同hashlib.digest()HMAC.hexdigest()同hashlib.hexdigest()HMAC.copy()同hashlib.copy()HMAC.digest_size同hashlib.digest_sizeHMAC.block_size同hashlib.block_sizeHMAC.name同hashlib.namehmac模块使用步骤 hmac模块模块的使用步骤与hashlib模块的使用步骤基本一致只是在第1步获取hmac对象时只能使用hmac.new()函数因为hmac模块没有提供与具体哈希算法对应的函数来获取hmac对象。 hmac模块使用实例 import hmac import hashlibh1 hmac.new(key, Hello, ) h1.update(World!) ret1 h1.hexdigest() print(type(ret1), len(ret1), ret1)h2 hmac.new(key, digestmodhashlib.md5) h2.update(Hello, World!) ret2 h2.hexdigest() print(type(ret2), len(ret2), ret2) 输出结果 (type str, 32, cfad9d610c1e548a03562f8eac399033) (type str, 32, cfad9d610c1e548a03562f8eac399033) 四、random与secrets模块介绍 random和secrets模块都是Pytthon内置的随机数操作模块其中secrets模块是Python 3.6才新增的模块。 1. random模块 random模块介绍 random模块实现了一个伪随机数生成器可用来生成随机数以及完成与随机数相关的功能。下面我们来介绍下该模块下常用的几个函数 函数名描述random.random()用于生成半开区间[0, 1.0)内的一个随机浮点数random.uniform(a, b)用于生成一个指定范文内[a, b]的随机浮点数random.randint(a, b)用于生成一个指定范围内[a, b]的整数random.randrange(start, stop[, step])用于从指定范围内[start, stop)按指定基数step递增的集合中获取一个随机数step默认值为1。random.randrange(stop)等价于random.randrange(0, stop)random.choice(seq)从指定序列seq中随机获取一个元素random.sample(population, k)从指定序列中随机获取k个不重复的元素并以列表形式返回用于不进行内容替换的随机抽样。random.shuffle(x[, random])用于随机打乱一个列表中元素需要注意的是该函数操作的是列表对象且没有返回值。 说明 1random.sample(population, k)只有在population中没有重复元素的情况下获取到的随机抽样结果才会有相同的元素2其实上面这些函数都是基于random.random()这个基础函数实现的3官方文章中有声明该模块完全不适合用作数据加密。 random模块实例 import randomprint(random.random(): , random.random()) print(random.uniform(10, 20): , random.uniform(10, 20)) print(random.randint(10, 20): , random.randint(10, 20)) print(random.randrange(10, 20, 2): , random.randrange(10, 20, 2)) print(random.choice(abcd1234): , random.choice(abcd1234)) print(random.sample(abcd1234, 3): , random.sample(abcd1234, 3)) print(random.sample(abcd1234, 3): , random.sample(abcd1234, 3)) print(random.shuffle([1, 2, 3, 4, 5, 6]): , random.shuffle([1, 2, 3, 4, 5, 6])) list [1, 2, 3, 4, 5, 6] random.shuffle(list) print(random.shuffle([1, 2, 3, 4, 5, 6]): , list) 输出结果 (random.random(): , 0.2967959697940342) (random.uniform(10, 20): , 10.774070602657055) (random.randint(10, 20): , 18) (random.randrange(10, 20, 2): , 18) (random.choice(abcd1234): , d) (random.sample(abcd1234, 3): , [d, 1, 4]) (random.sample(abcd1234, 3): , [d, d, d]) (random.shuffle([1, 2, 3, 4, 5, 6]): , None) (random.shuffle([1, 2, 3, 4, 5, 6]): , [5, 1, 2, 4, 3, 6]) 再次说明random.shuffle()的函数没有返回结果且其操作的参数必须是一个列表对象。 2. secrets模块 secrets模块介绍 secrets模块是Python 3.6新增的内置模块它可以生成用于管理密码、账户验证信息、安全令牌和相关秘密信息等数据的密码强随机数。需要特别声明的是与random模块中的默认伪随机数生成器相比我们应该优先使用secrets模块因为random模块中的默认伪随机数生成器是为建模和模拟而设计的不是为安全或密码学而设计的。总体来讲我们可以通过secrets模块完成两种操作 1生成安全随机数2生成一个笃定长度的随机字符串--可用作令牌和安全URLsecrets模块提供的函数 下面来看下secrets模块提供的函数 函数名描述secrets.choice(sequence)功能与random.choice(seq)相同从指定的非空序列中随机选择一个元素并返回secrets.randbelow(n)功能与random.randrange(n)相同从半开区间[0, n)内随机返回一个整数secrets.randbits(k)返回一个带有k个随机位的整数secrets.token_bytes([nbytesNone])返回一个包含nbytes个字节的随机字节串secrets.token_hex([nbytesNone])返回一个包含nbytes字节的16进制格式的随机文本字符串每个字节被转成成2个16进制数字这可以用来生成一个随机密码。secrets.token_urlsafe([nbytes])返回一个包含nbytes个字节的随机安全URL文本字符串这可以在提供重置密码的应用中用来生成一个临时的随机令牌secrets.compare_digest(a, b)比较字符串a和字符串b是否相等相等则返回True否则返回False 如果以上函数中的nbytes参数未提供或设置为None则会取一个合理的默认值。那么生成一个令牌token时应该使用多个字节呢 为了抵抗暴力破解攻击令牌需要有足够的随机性当生成令牌使用的字节数越多时暴力破解需要尝试的次数就越多。因此当计算机的计算能力变得更强时也就意味着计算可以再更短的时间内完成更多的猜测次数。因此这里所使用的字节个数不应该是一个固定的值而是应该随着计算机计算能力的增强而增加。到2015年为止我们相信32个字节256bits的随机性对于secrets模块的典型应用场景来说是足够的了。 secrets模块的最佳实践 实例1 生成一个由8位数字和字母组成的随机密码 import secrets import stringalphanum string.ascii_letters string.digits password .join(secrets.choice(alphanum) for i in range(8)) 实例2 生成一个由10位数字和字母组成的随机密码要求至少有一个小写字符至少一个大写字符 和 至少3个数字 import secrets import stringalphanum string.ascii_letters string.digits while True:password .join(secrets.choice(alphanum) for i in range(10))if (any(c.islower() for c in password)and any(c.isupper() for c in password)and len(c.isdigit() for c in password) 3):break 实例3 生成一个用于找回密码应用场景的、包含一个安全令牌的、很难猜到的临时URL import secrets url https://mydomain.com/reset secrets.token_urlsafe() 说明 secrets模块是Python 3.6新增的内置模块尽管官方文档中强调过random模块并不适合用来做安全和加密相关的工作但是在Python 3.6之前我们还是可以用random模块来模拟secrets模块提供的这些功能的实现。 五、base64模块介绍 经常听到有人说“base64加密”其实base64并不能用于数据加密它也不是为了纯粹的数据加密而生的它的出现是为了解决不可见字符串的网络传输和数据保存问题。因为用base64对数据进行转换的过程不能成为“加密”与“解密”只能成为“编码”与“解码”。下面我们也会用到它所以这里顺便做下简单的介绍。 1. base64的作用 Base64是一种用64个字符来表示任意二进制数据的方法它是一种通过查表对二进制数据进行编码的方法不能用于数据加密。base64最初的出现时为了能够正确的传输邮件数据因为邮件中的附件比如图片的二进制数中可能存在不可见字符ascii码中128-255之间的值是不可见字符比如我们尝试用记事本或其他文本编辑器打开一个图片时通常都会看到一大堆乱码这些乱码就是不可见字符。由于早期的一些网络设备和网络协议是无法正确识别这些字符的这就可能在数据传输时出现各种无法预知的问题。base64的作用就是把含有不可见字符的信息用可见字符来表示Ascii码中0-127之间的值是可见字符从而解决这个问题。 关于base64的介绍及实现原理可以看看这几篇文章 http://www.cnblogs.com/wellsoho/archive/2009/12/09/1619924.htmlhttps://www.zhihu.com/question/36306744/answer/http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001399413803339f4bbda5c01fc479cbea98b13873907480002. base64的常见应用场景 base64适用于小段内容的编码比如数字证书的签名、URL、Cookie信息等需要通过网络进行传输的小段数据。关于base64在数字签名中的应用会在本文后面讲解pycrypto模块使用实例时有具体的应用示例。 3. base64模块介绍及简单使用示例 Python中有一个内置的base64模块可直接用来进行base64的编码和解码工作--即提供 “二进制数据” 与 “可打印可见的ASCII字符”之间的转换功能。常用的函数有以下几个 函数名描述base64.b64encode(s, altcharsNone)对二进制数据字节串s通过base64进行编码返回编码后的字节串base64.b64decode(s, altcharsNone, validateFalse)对通过base64编码的字节对象或ASCII字符串s进行解码返回解码后的字节串base64.urlsafe_b64encode(s)与b64encode()函数不同的是它会把标准Base64编码结果中的字符和字符/分别替换成字符-和字符_。base64.urlsafe_b64decode(s)解码通过base64.urlsafe_b64encode()函数编码的字节对象或ASCII字符串s。 提示 URL中有一些有特殊意义的字符,也就是保留字符:;, /, ?, :, , , , , $ 和 , 在URL的参数值中应该避免这些字符的出现。 下面来看个简单的示例 import base64data hello, 世界 based_data1 base64.b64encode(data) plain_data1 base64.b64decode(based_data1) based_data2 base64.urlsafe_b64encode(data) plain_data2 base64.urlsafe_b64decode(based_data2) print(based_data1) print(based_data2) print(plain_data1) print(plain_data2) 输出结果 aGVsbG8sIOS4lueVjO8gQ aGVsbG8sIOS4lueVjO-8gQ hello, 世界 hello, 世界 3. base64编码结果后的等号 通过上面的这个简单示例的输出结果会发现随翻urlsafe_b64encode()函数会把编码结果中的字符和字符/替换成其他URL的非保留字符但是它的编码结果中还是可能出现字符。那么这些字符代表什么呢能否去掉呢 其实base64编码的过程中会先把原来数据中的每3个字节的二进制数据编码为4个字节的文本数据当原始数据最后不满3个字节时就需要用\00字节进行补位凑够3个字节而且会在编码结果的最后加上相应个数的号来表示补了多少个字节这样解码的时候就可以去掉那些补位的字节。 由此我们可以得出两个结论 1base64编码后的结果的末尾可能存在字符个数分别是0个、1个和2个2base64编码后的结果应该是4的倍数。基于以上第2个结论为了避免编码结果中可能出现的的字符对网络数据传输造成影响可以在传出前去掉后面的字符接收方可以通过对数据的长度对4求模得到应该补上的字符个数从而得到正确的数据。比如我们可以通过下面这个解码函数来完成这个过程 import base64def safe_b64decode(s):length len(s) % 4for i in range(length):s s return base64.b64decode(s)if __name__ __main__:print(safe_b64decode(aGVsbG8sIOS4lueVjO8gQ))print(safe_b64decode(aGVsbG8sIOS4lueVjO8gQ))print(safe_b64decode(aGVsbG8sIOS4lueVjO8gQ)) 输出结果 hello, 世界 hello, 世界 hello, 世界 可见虽然我们把上面那个示例中通过base64编码后的结果后面的字符去掉了通过我们自己定义的safe_b64decode()函数最终得到了正确的解码结果。 六、pycrypto模块 1. pycryto模块介绍 pycryto模块不是Python的内置模块它的官方网站地址是这里。pycrypto模块是一个实现了各种算法和协议的加密模块的结合提供了各种加密方式对应的多种加密算法的实现包括 单向加密、对称加密以及公钥加密和随机数操作。而上面介绍的hashlib和hmac虽然是Python的内置模块但是它们只提供了单向加密相关算法的实现如果要使用对称加密算法如, DESAES等或者公钥加密算法我们通常都是使用pycryto这个第三方模块来实现。 需要注意的是pycrypto模块最外层的包package不是pycrypto而是Crypto。它根据加密方式类别的不同把各种加密方法的实现分别放到了不同的子包sub packages中且每个加密算法都是以单独的Python模块一个.py文件存在的。我们来看下这些子包 包名描述Crypto.Hash该包中主要存放的是单向加密对应的各种哈希算法/散列算法的实现模块如MD5.py, SHA.pySHA256.py等。Crypto.Cipher该包中主要存放的是对称加密对应的各种加密算法的实现模块如DES.py, AES.py, ARC4.py等以及公钥加密对应的各种加密算法的实现模块如PKCS1_v1_5.py等。Crypto.PublicKey该包中主要存放的是公钥加密与签名算法的实现模块如RSA.py, DSA.py等。Crypto.Signatue该包中主要存放的是公钥签名相关算法的实现模块如PKCS1_PSS.py, PKCS1_v1_5.py。Crypto.Random该包中只有一个随机数操作的实现模块 random.pyCrypto.Protocol该包中存放的是一些加密协议的实现模块如Chaffing.py, KDF.py等。Crypto.Util该包存放的是一些有用的模块和函数 这里需要说明的是Crypto.PublicKey子包下的RSA.py和DSA.py模块只是用来生成秘钥对的而基于公钥的加密与解密功能是由Crypto.Cipher子包下的PKCS1_v1_5.py或PKCS1_OAEP.py以这个密钥对儿为密钥来实现的同样签名与验证相关算法的功能是由Crypto.Signature子包下的PKCS1_v1_5.py和PKCS1_PASS.py以这个密钥对而为密钥来实现的。 2. pycrypto的安装与使用 pycrypto的安装 由于pycryto不是Python的内置模块所以在使用它之前需要通过Python模块管理工具(如pip)来安装。不幸的是如果你使用的是Windows平台会遇到一些问题比如执行pip install pycryto命令来安装pycrpto时可能会得到以下错误提示信息 error: Microsoft Visual C 9.0 is required (Unable to find vcvarsall.bat). 或 error: Unable to find vcvarsall.bat 这是由于pycrypto模块是用C语言实现的Python模块管理工具在安装它时需要使用C/C编译工具对它的代码进行编译但是找不到对应版本的编译工具具体解释及解决方案请查看《这篇博文》。 pycrypto的使用方式 由于pycrypto把不同的类别加密算法的实现模块都放到了Crypto下不同的子包下了所以我们只需要确定我们所需要使用的加密算法的实现模块在哪个子包下然后导入相应的实现模块就可以使用了。比如我们打算使用MD5算法就可以通过from Crypto.Hash import MD5来导入MD5这个模块然后就可以使用该模块相应的api了。 pycrypto使用实例 实例1 使用SHA256算法获取一段数据的摘要信息 from Crypto.Hash import SHA256hash SHA256.new() hash.update(Hello, World!) digest hash.hexdigest() print(digest) 输出结果 dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f 实例2 使用AES算法加密解密一段数据 from Crypto.Cipher import AES# 加密与解密所使用的密钥长度必须是16的倍数 secret_key ThisIs SecretKey # 要加密的明文数据长度必须是16的倍数 plain_data Hello, World123! # IV参数长度必须是16的倍数 iv_param This is an IV456# 数据加密 aes1 AES.new(secret_key, AES.MODE_CBC, iv_param) cipher_data aes1.encrypt(plain_data) print(cipher data, cipher_data)# 数据解密 aes2 AES.new(secret_key, AES.MODE_CBC, This is an IV456) plain_data2 aes2.decrypt(cipher_data) # 解密后的明文数据 print(plain text, plain_data2) 输出结果 (cipher data\xef\xbc\x9a, \xcb\x7fd\x03\x12T,\xbe\x91\xac\x1a\xd5\xaa\xe6P\x9a) (plain text\xef\xbc\x9a, Hello, World123!) 实例3 随机数操作 from Crypto.Random import randomprint(random.randint: , random.randint(10, 20)) print(random.randrange: , random.randrange(10, 20, 2)) print(random.randint: , random.getrandbits(3)) print(random.choice: , random.choice([1, 2, 3, 4, 5])) print(random.sample: , random.sample([1, 2, 3, 4, 5], 3)) list [1, 2, 3, 4, 5] random.shuffle(list) print(random.shuffle: , list) 输出结果 (random.randint: , 10L) (random.randrange: , 10L) (random.randint: , 5L) (random.choice: , 5) (random.sample: , [5, 4, 2]) (random.shuffle: , [5, 2, 1, 3, 4]) 实例4 使用RSA算法生成密钥对儿 生成秘钥对 from Crypto import Random from Crypto.PublicKey import RSA# 获取一个伪随机数生成器 random_generator Random.new().read # 获取一个rsa算法对应的密钥对生成器实例 rsa RSA.generate(1024, random_generator)# 生成私钥并保存 private_pem rsa.exportKey() with open(rsa.key, w) as f:f.write(private_pem)# 生成公钥并保存 public_pem rsa.publickey().exportKey() with open(rsa.pub, w) as f:f.write(public_pem) 私钥文件rsa.key的内容为 -----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQCo7vV5xSzEdQeFq9n5MIWgIuLTBHuutZlFvEd8fIk3yC4So/d y1f64iuYFcDeNU7eVGqTSkHmAl4AihDXoaH6hxohrcX0bCg0jVoQMe2zID7MzcE d50FhJbuG6JsWtYzLUYs7/cQ3urZYwB4PEVa0WxQj2aXUMsxp6vl1CgB4QIDAQAB AoGAS/I5y4e4S43tVsvej6efu1FTtdhDHlUn1fKgawz1dlwVYqSqruSW5gQ94v6M mZlPnqZGz3bHz3bqcUYM0jH/5Tygz4adosziRCUbjMsFePbJ4nvGC/1hwQweCm 7sxog4sw91FrOfAg/iCcoeho0DghDolH9zzwRYPIWUyUECQQDFGeqccGwL9cU vGmZxtF8GkRL7YrXI7cvnZhnZZ7TANjxlYukLGEpiFGIDd0Aky1QhkK18L8DTO4 iGXTpgJAkEA22o03/1IqeRBofbkkDmndArHNUnmv5pyVFaLKPoVgA4A1YsvqxUL DK6RwFGONUMknBWY59EDKCUdIf3CsVIhGQJAJKDMRB19xBMv4iBCe9z/WYDy1YnL TcWWmvkeIMfbVjBrFNif3WlwQ9lnp5OHGpzuymRtKPGtv49ohECfi3HEmQJAPIn AoAdk07Up8b3TccoinrbCj2uMH/dongpTHJx2uWDVr6kEUhpKF2d1fLYaYjr7VC XBHTxjvgO6aYG2to2QJBAIzDugOSTeQFpidCoewfa0XX4guFWRf8wzyBC/XE6TY 3cIY05sjbpfiVwW/Cb8Z2ia8EgBTGN8HSIFOUQ2jRl4 -----END RSA PRIVATE KEY----- 公钥文件rsa.pub的内容为 -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo7vV5xSzEdQeFq9n5MIWgIuLT BHuutZlFvEd8fIk3yC4So/dy1f64iuYFcDeNU7eVGqTSkHmAl4AihDXoaH6hxoh rcX0bCg0jVoQMe2zID7MzcEd50FhJbuG6JsWtYzLUYs7/cQ3urZYwB4PEVa0WxQ j2aXUMsxp6vl1CgB4QIDAQAB -----END PUBLIC KEY----- 实例5 公钥加密算法的实现 前面说过公钥加密算法是由Crypto.Cipher子包下的PKCS1_v1_5.py或PKCS1_OAEP.py模块以已经存在的密钥对儿为密钥来实现的现在常用的是PKCS1_v1_5。另外我们前面提到过使用对方的公钥加密使用对方的私钥解密才能保证数据的机密性因此这里以上面生成的公钥进行加密数据以上面生成的私钥解密数据 from Crypto import Random from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5 import base64# 数据加密 message This is a plain text. with open(rsa.pub, r) as f:public_key f.read()rsa_key_obj RSA.importKey(public_key)cipher_obj Cipher_PKCS1_v1_5.new(rsa_key_obj)cipher_text base64.b64encode(cipher_obj.encrypt(message))print(cipher test: , cipher_text)# 数据解密 with open(rsa.key, r) as f:private_key f.read()rsa_key_obj RSA.importKey(private_key)cipher_obj Cipher_PKCS1_v1_5.new(rsa_key_obj)random_generator Random.new().readplain_text cipher_obj.decrypt(base64.b64decode(cipher_text), random_generator)print(plain text: , plain_text) 输出结果 (cipher test: , oq1sOSz4lS9PgrKmiwuAHs7iUhmWMvWdEbXLTOdhGtyIAr6xwmjtnBNpuvMVIM2Mz/O/xVzPu5L8nzUVW2THKpQinNwC7JWF0wnxrTHwKrmfXIIxxibQJS02obxkoEeqrjRo0b8V7yktYIV3ig2SlU3yjcrlOFmRXh6dE2TAI) (plain text: , This is a plain text.) 实例6 数据签名与签名验证的实现 同样签名与验证相关算法的功能是由Crypto.Signature子包下的PKCS1_v1_5.py和PKCS1_PASS.py以这个密钥对而为密钥来实现的。数据签名的目的是为了防止别人篡改发送人的原始数据其原理是 1先以单向加密方式通过某种哈希算法如MD5SHA1等对要发送的数据生成摘要信息数据指纹2然后发送方用自己密钥对儿中的私钥对这个摘要信息进行加密3数据接收方用发送的公钥对加密后的摘要信息进行解密得到数据摘要的明文A4数据接收方再通过相同的哈希算法计算得到数据摘要信息B5数据接收方对比数据摘要A与数据摘要B如果两者一致说明数据没有被篡改过。from Crypto.Hash import SHA from Crypto.Signature import PKCS1_v1_5 as Signature_PKCS1_v1_5 message This is the message to send. # 数据签名 with open(rsa.key, r) as f:private_key f.read()rsa_key_obj RSA.importKey(private_key)signer Signature_PKCS1_v1_5.new(rsa_key_obj)digest SHA.new()digest.update(message)signature base64.b64encode(signer.sign(digest))print(signature text: , signature)# 验证签名 with open(rsa.pub, r) as f:public_key f.read()rsa_key_obj RSA.importKey(public_key)signer Signature_PKCS1_v1_5.new(rsa_key_obj)digest SHA.new(message)is_ok signer.verify(digest, base64.b64decode(signature))print(is ok: , is_ok) 输出结果 (signature text: , Bb4gvPU9Ji63kk3SSTiAVLctDbdb91DQuQKecbTcO2Jvpwbr7fr9sKZOvZ8LIuSOdJkhbGX6swsSNwDI/CoT0xCdjiasfySPgsLyTcSWLyy9P7SrDuveH1ABUR/oYisvT1wFsScu0NMOBR8sLpboPk2DiW6n400jZq7t09xUyc) (is ok: , True) 上面这几个关于pycrpto的使用实例来自这里。 七、总结 上面讲了很多内容现在我们简单总结下 数据加密方式大体分为3类单向加密、对称加密 和 公钥加密非对称加密。这3类加密方式都各自包含不同的加密算法如单向加密方式中包含MD5、SHA1、SHA256等这些算法又称为“哈希算法”或“散列算法”或“数据摘要算法”Python内置的hashlib和hmac只提供了单向加密的各种算法实现如果要做对称加密或者公钥加密操作需要安装第三方扩展模块常用的是pycrypto模块。另外hmac允许在使用哈希算法计算数据摘要时使用一个密钥。随机数操作可以通过三个模块来做Python内置的random模块和secrets模块Python 3.6中才可用还可以通过pycrypto模块中的Crypto.Random子包中的模块来完成。base64只适合编码小段数据且不能用于数据加密算法是公开的且没有密钥所有人都可以解码pycrypto是一个加密算法库几乎所有的加密算法都可以在它里面找到相应的实现模块。八、参考文档 https://docs.python.org/3/library/hashlib.htmlhttps://docs.python.org/3/library/hmac.htmlhttps://docs.python.org/3/library/random.htmlhttps://docs.python.org/3/library/secrets.htmlhttps://www.dlitz.net/software/pycrypto/相关源码的注释信息转载来源https://www.cnblogs.com/yyds/p/7072492.html   转载于:https://www.cnblogs.com/honey-badger/p/9742643.html
http://wiki.neutronadmin.com/news/87621/

相关文章:

  • 好看的企业网站源码网站建设公司扬州
  • 做场景秀的网站如何推广外贸型网站
  • 建站小程序编辑器闪亮登场用python做电商网站
  • 怎么制作微信购物网站山东大学信息服务平台
  • 婚庆网站建设策划案深圳房地产网站建设
  • 商城网站有什么好处黑色网站模板
  • 建设银行网站app一个大佬做的本子网站
  • 网站开发公司怎么选择网站开发者模式下载视频
  • 网站外包多少钱兰州市做网站的企业有哪些
  • 山东城市建设厅网站wordpress pdf 打印
  • 南京h5网站开发莱芜金点子电子版
  • 室内设计素材网站大全境外网站可以备案吗
  • 株洲建设企业网站oa系统网站建设
  • 深圳网站建设网站推广方案设计欣赏网
  • 做网站如何链接邮箱谷歌浏览器对做网站有什么好处
  • 用软件做模板下载网站中油即时通信电脑版
  • 可以刮刮卡的网站无锡网站营销公司
  • 全站仪建站流程什么是域名为什么需要它
  • 建设网站优点免费建立平台网站
  • 软路由系统如何做网站wordpress执行生命周期
  • 自己可以建设网站吗文化建设宣传标语
  • 帆客建设网站宝塔面板加wordpress建站
  • 用文本文档做网页wordpress 内存优化
  • flash网站模板下载做投票链接网站
  • 厦门网站建设建网站网站首页包含的内容怎么做
  • 自己建网站网站优化外包价格
  • 织梦网站统计代码wordpress的版本号
  • 智慧团建入口龙岗网站优化培训
  • 手机版网站建设价格中国土木工程网
  • 企业融资论文广州seo网站营销