神级程序员带来:用python有证书的加密解密实现方法!

本文实例讲述了python有证书的加密解密实现方法。分享给大家供大家参考。具体实现方法如下:

最近在做python的加解密工作,同时加完密的串能在php上能解出来,网上也找了一些靠谱的资料,刚好也有时间我就总结了一下python在加密与解密这块的代码,今后可能还能用的上。相对于php而言python这块加解密组件较多的,分别是:

一、 RSA标准方式生成的证书

1.加密解密、加密签名、验证加密签名

代码如下:

#encoding: utf8

import os

import M2Crypto

#随机数生成器(1024位随机)

M2Crypto.Rand.rand_seed(os.urandom(1024))

#生成一个1024位公钥与私密钥证书

Geekso = M2Crypto.RSA.gen_key(1024, 65537)

Geekso.save_key(‘jb51.net-private.pem‘, None)

Geekso.save_pub_key(‘jb51.net-public.pem‘)

#使用公钥证书加密开始

WriteRSA = M2Crypto.RSA.load_pub_key(‘jb51.net-public.pem‘)

CipherText = WriteRSA.public_encrypt("这是一个秘密消息,只能用私钥进行解密",M2Crypto.RSA.pkcs1_oaep_padding)

print "加密的串是:"

print CipherText.encode(‘base64‘)

#对加密串进行签名

MsgDigest = M2Crypto.EVP.MessageDigest(‘sha1‘)

MsgDigest.update(CipherText)

#提示,这里也可以使用私钥签名

#WriteRSA = M2Crypto.RSA.load_key (‘jb51.net-private.pem‘)

#Signature = WriteRSA.sign_rsassa_pss(MsgDigest.digest())

Signature = Geekso.sign_rsassa_pss(MsgDigest.digest())

print "签名的串是:"

print Signature.encode(‘base64‘)

#使用私钥证书解密开始

ReadRSA = M2Crypto.RSA.load_key (‘jb51.net-private.pem‘)

try:

PlainText = ReadRSA.private_decrypt (CipherText, M2Crypto.RSA.pkcs1_oaep_padding)

except:

print "解密错误"

PlainText = ""

if PlainText :

print "解密出来的串是:"

print PlainText

# 验证加密串的签名

MsgDigest = M2Crypto.EVP.MessageDigest(‘sha1‘)

MsgDigest.update(CipherText)

#提示,如果是用私钥签名的那就用公钥验证

#VerifyRSA = M2Crypto.RSA.load_pub_key(‘Alice-public.pem‘)

#VerifyRSA.verify_rsassa_pss(MsgDigest.digest(), Signature)

if Geekso.verify_rsassa_pss(MsgDigest.digest(), Signature) == 1:

print "签名正确"

else:

print "签名不正确"

2.字符串生成签名、验证签名

代码如下:

#用私钥签名

SignEVP = M2Crypto.EVP.load_key(‘jb51.net-private.pem‘)

SignEVP.sign_init()

SignEVP.sign_update(‘来自这一客(http://www.jb51.net)的签名串‘)

StringSignature = SignEVP.sign_final()

print "签名串是:"

print StringSignature.encode(‘base64‘)

#用公钥验证签名

PubKey = M2Crypto.RSA.load_pub_key(‘jb51.net-public.pem‘)

VerifyEVP = M2Crypto.EVP.PKey()

VerifyEVP.assign_rsa(PubKey)

VerifyEVP.verify_init()

VerifyEVP.verify_update(‘来自这一客(http://www.jb51.net)的签名串‘)

if VerifyEVP.verify_final(StringSignature) == 1:

print "字符串被成功验证。"

else:

print "字符串验证失败!"

3.给证书加上密码

给证书加密码的好处是即使证书被人拿了,没有密码也用不了。

代码如下:

def passphrase(v):

return ‘4567890‘

生成证书时用

代码如下:

Geekso.save_key(‘jb51.net-private.pem‘,callback=passphrase)

使用证书时用

代码如下:

ReadRSA = RSA.load_key (‘jb51.net-private.pem‘, passphrase)

二、 X509标准方式生成的证书1.生成证书、公钥文件、私钥文件

代码如下:

import time

from M2Crypto import X509, EVP, RSA, ASN1

def issuer_name():

"""

证书发行人名称(专有名称)。

Parameters:

none

Return:

X509标准的发行人obj.

"""

issuer = X509.X509_Name()

issuer.C = "CN" # 国家名称

issuer.CN = "*.jb51.net" # 普通名字

issuer.ST = "Hunan Changsha"

issuer.L = "Hunan Changsha"

issuer.O = "Geekso Company Ltd"

issuer.OU = "Geekso Company Ltd"

issuer.Email = "[email protected]"

return issuer

def make_request(bits, cn):

"""

创建一个X509标准的请求。

Parameters:

bits = 证书位数

cn = 证书名称

Return:

返回 X509 request 与 private key (EVP).

"""

rsa = RSA.gen_key(bits, 65537, None)

pk = EVP.PKey()

pk.assign_rsa(rsa)

req = X509.Request()

req.set_pubkey(pk)

name = req.get_subject()

name.C = "US"

name.CN = cn

req.sign(pk,‘sha256‘)

return req, pk

def make_certificate_valid_time(cert, days):

"""

从当前时间算起证书有效期几天。

Parameters:

cert = 证书obj

days = 证书过期的天数

Return:

none

"""

t = long(time.time()) # 获取当前时间

time_now = ASN1.ASN1_UTCTIME()

time_now.set_time(t)

time_exp = ASN1.ASN1_UTCTIME()

time_exp.set_time(t + days * 24 * 60 * 60)

cert.set_not_before(time_now)

cert.set_not_after(time_exp)

def make_certificate(bits):

"""

创建证书

Parameters:

bits = 证快的位数

Return:

证书, 私钥 key (EVP) 与 公钥 key (EVP).

"""

req, pk = make_request(bits, "localhost")

puk = req.get_pubkey()

cert = X509.X509()

cert.set_serial_number(1) # 证书的序例号

cert.set_version(1) # 证书的版本

cert.set_issuer(issuer_name()) # 发行人信息

cert.set_subject(issuer_name()) # 主题信息

cert.set_pubkey(puk)

make_certificate_valid_time(cert, 365) # 证书的过期时间

cert.sign(pk, ‘sha256‘)

return cert, pk, puk

# 开始创建

cert, pk, puk= make_certificate(1024)

cert.save_pem(‘jb51.net-cret.pem‘)

pk.save_key(‘jb51.net-private.pem‘,cipher = None, callback = lambda: None)

puk.get_rsa().save_pub_key(‘jb51.net-public.pem‘)

2.用证书加密、私钥文件解密

代码如下:

def geekso_encrypt_with_certificate(message, cert_loc):

"""

cert证书加密,可以用私钥文件解密.

Parameters:

message = 要加密的串

cert_loc = cert证书路径

Return:

加密串 or 异常串

"""

cert = X509.load_cert(cert_loc)

puk = cert.get_pubkey().get_rsa() # get RSA for encryption

message = base64.b64encode(message)

try:

encrypted = puk.public_encrypt(message, RSA.pkcs1_padding)

except RSA.RSAError as e:

return "ERROR encrypting " + e.message

return encrypted

encrypted = geekso_encrypt_with_certificate(‘www.jb51.net‘,‘jb51.net-cret.pem‘)

print ‘加密串‘,encrypted

def geekso_decrypt_with_private_key(message, pk_loc):

"""

私钥解密证书生成的加密串

Parameters:

message = 加密的串

pk_loc = 私钥路径

Return:

解密串 or 异常串

"""

pk = RSA.load_key(pk_loc) # load RSA for decryption

try:

decrypted = pk.private_decrypt(message, RSA.pkcs1_padding)

decrypted = base64.b64decode(decrypted)

except RSA.RSAError as e:

return "ERROR decrypting " + e.message

return decrypted

print ‘解密串‘,geekso_decrypt_with_private_key(encrypted, ‘jb51.net-private.pem‘)

3.用私钥加密、证书解密

代码如下:

def geekso_encrypt_with_private_key(message,pk_loc):

"""

私钥加密

Parameters:

message = 加密的串

pk_loc = 私钥路径

Return:

加密串 or 异常串

"""

ReadRSA = RSA.load_key(pk_loc);

message = base64.b64encode(message)

try:

encrypted = ReadRSA.private_encrypt(message,RSA.pkcs1_padding)

except RSA.RSAError as e:

return "ERROR encrypting " + e.message

return encrypted

encrypted = geekso_encrypt_with_private_key(‘www.jb51.net‘, ‘jb51.net-private.pem‘)

print encrypted

def geekso_decrypt_with_certificate(message, cert_loc):

"""

cert证书解密.

Parameters:

message = 要解密的串

cert_loc = cert证书路径

Return:

解密后的串 or 异常串

"""

cert = X509.load_cert(cert_loc)

puk = cert.get_pubkey().get_rsa()

try:

decrypting = puk.public_decrypt(message, RSA.pkcs1_padding)

decrypting = base64.b64decode(decrypting)

except RSA.RSAError as e:

return "ERROR decrypting " + e.message

return decrypting

decrypting = geekso_decrypt_with_certificate(encrypted, ‘jb51.net-cret.pem‘)

print decrypting

4.用私钥签名、证书验证签名

代码如下:

def geekso_sign_with_private_key(message, pk_loc, base64 = True):

"""

私钥签名

Parameters:

message = 待签名的串

pk_loc = 私钥路径

base64 = True(bease64处理) False(16进制处理)

Return:

签名后的串 or 异常串

"""

pk = EVP.load_key(pk_loc)

pk.sign_init()

try:

pk.sign_update(message)

signature = pk.sign_final()

except EVP.EVPError as e:

return "ERROR signature " + e.message

return signature.encode(‘base64‘) if base64 is True else signature.encode(‘hex‘)

signature = geekso_sign_with_private_key(‘www.jb51.net‘,‘jb51.net-private.pem‘)

print signature

def geekso_verifysign_with_certificate(message, signature, cert_loc, base64 = True):

"""

证书验证签名

Parameters:

message = 原来签名的串

signature = 签名后的串

cert_loc = 证书路径文件

base64 = True(bease64处理) False(16进制处理)

Return:

成功or失败串 or 异常串

"""

signature = signature.decode(‘base64‘) if base64 is True else signature.decode(‘hex‘)

cert = X509.load_cert(cert_loc)

puk = cert.get_pubkey().get_rsa()

try:

verifyEVP = EVP.PKey()

verifyEVP.assign_rsa(puk)

verifyEVP.verify_init()

verifyEVP.verify_update(message)

verifysign = verifyEVP.verify_final(signature)

if verifysign == 1 :

return ‘成功‘

else :

return ‘失败‘

except EVP.EVPError as e:

return "ERROR Verify Sign " + e.message

print geekso_verifysign_with_certificate(‘www.jb51.net‘, signature, ‘jb51.net-cret.pem‘)

希望本文所述对大家的Python程序设计有所帮助。

欢迎加入我的千人交流学习答疑群:125240963

原文地址:https://www.cnblogs.com/Python1234/p/9146747.html

时间: 2024-10-27 02:55:31

神级程序员带来:用python有证书的加密解密实现方法!的相关文章

神级程序员巧用python开发王者荣耀把妹神器,一路升级上王者!

Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务.它的语法非常简捷和清晰,与其它大多数程序设计语言不一样,它使用缩进来定义语句. Python支持命令式程序设计.面向对象程序设计.函数式编程.面向切面编程.泛型编程多种编程范式.与Scheme.Ruby.Perl.Tcl等动态语言一样,Python具备垃圾回收

神级程序员教你用Python实现简单的导弹自动追踪!此乃装逼神技!

由于待会要用pygame演示,他的坐标系是y轴向下,所以这里我们也用y向下的坐标系. 计算sina和cosa,正弦对比斜,余弦邻比斜,斜边可以利用两点距离公式计算出,即: 于是 AC的长度就是导弹的速度乘以时间即 |AC|=vt,然后即可计算出AD和CD的长度,于是这一个时间片过去后,导弹应该出现在新的位置C点,他的坐标就是老的点A的x增加AD和y减去CD. 于是,新的C点坐标就是: 只要一直反复循环执行这个操作即可,好吧,为了更形象,把第一个时间片和第二个时间片放在一起看看: 很简单的代码如下

神级程序员教你如何用四行代码画出一幅中国地图!Python就是牛逼

前面两行引入相应的库,真正的代码就4行,够简单吧.第1行甚至可以不写,它定义了图的大小.第2行我们创建一个地图,第3行把海岸线画上,第4行显示这个地图,就是这样: 你用 Java 的 4 行代码画一个地图出来? 然后我们开始画上国家,又是1行代码: m.drawcountries(linewidth=1.5) 就变成了这样: 看上去有点变形,这是因为我们没有添加任何投影的原因, Basemap 提供 24 种不同的投影方式,你可以自己一个个试一下,比较常用的是 兰勃特投影 ,我们添加一下: m

科技巨擎Google是如何构建Web框架的,神级程序员操作指南

根据谷歌对外公布的数据,它的20亿行代码都部署在同一个代码仓库里,通过基于基线的方式进行开发工作中的代码共享. 从上面这张图可以看到,一共有文件10亿个,源文件数量达到900万个,源代码行数达到20亿行,提交代码的深度可以挖掘到3500万次提交,平均每个工作日提交4万次,数字真是恐怖. 从大众的眼光来看,特别是那些谷歌公司外部的人,他们会觉得这种单一代码仓库的管理方式,尤其是代码量这么恐怖的前提下,这种管理方式很不正常,但是它真的很有效,而这种有效是由管理方式决定的,而不是单纯让它自然生长. R

好程序员web前端分享CSS文件引用的最优方法

好程序员web前端分享CSS文件引用的最优方法,在html总引入css文件的方法: 1链接式: 2导入式: 区别: 使用链接式时,会在加载页面主体部分之前加载css文件,这样现实出来的页面一开始就是带有样式效果的,而使用导入式时,会在整个页面装载完成之后再装载css文件,对于有的浏览器来说,在一些情况下,如果页面文件的体积比较大,则会出现先现实无样式的页面,闪烁一下之后再出现设置样式的效果.从浏览者的感受来说,这是使用导入式的一个缺陷.** 链接式比导入式快. 当有多个文件链接到页面的时候会导致

python AES 双向对称加密解密

高级加密标准(Advanced Encryption Standard,AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准.2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一.AES只是个基本算法,实现AES有若干模式.其中

程序员的瑞士军刀----Python

这篇文章比较难以成型.大概想表达的意思是,程序员应该通过脚本语言来完成一些"批量"或"自动化"的操作,而不是重复的去做体力劳动. 具体方式因人而异,比如有人非常熟悉bat或者shell的编写,或者有人非常熟悉php.perl的编写,而我更早接触了Python,所以很多工具更加习惯用Python来完成. 这里会先讲一下我的各种需求,以及脚本语言的选择,后面会针对Python逐渐补全很多"惯用法",把自己常用的功能和代码段记录下来. 一.综述 Pyt

编程给程序员带来哪些坏习惯

似乎任何职业都会给从业人员带来这样那样的习惯.国外某网站上有位朋友(应该也是程序员)想了解其他程序员在投身堆码事业后有什么样的坏习惯.结果一呼百应,很多程序员纷纷自爆自己的坏习惯和糗人糗事.编程无国界,相信国内堆码界的朋友,也会有同感. 1. 编程已给我带来很多坏习惯,编程也每天在继续给我新增更多的坏习惯.当然有些习惯和编程无关了.下面这些习惯尽管我也很想改掉,但已根深蒂固. a. 在天地万物中,去发现多态.继承和模式: b. 用十六进制代码中的像素和颜色来解释某东西的大小: c. 在日常交谈中

[python]通过微信公众号“Python程序员”,编写python代码

今天发现微信公众号中,居然可以编写python代码,很是惊喜,觉得蛮有趣的. 步骤如下: 1.关注微信公众号“Python程序员” 2.关注成功后,点击右下角的“潘多拉”->"Python终端“->"阅读原文”. 3.Python开发页面被打开,在下面的输入框内,输入python代码,点击确认即可. 可以用来练习python,是不是很有趣呢?