python中的密码算法模块pycrypto

来源:互联网 发布:竞争排斥 知乎 编辑:程序博客网 时间:2024/06/07 03:13
密码技术的用途主要源于两个方面,加密/解密和签名/验签。在信息传播中,通常有发送者,接受者和窃听者三个角色。假设发送者Master想要写信给接受者Ghost,可是又不想信的内容被别人看到,因此Master需要先对信加密,而Ghost收到信之后又能解密。这样别的人即使窃听盗取了密文也无法解密。其次,如果窃听者并不想破译内容,而是伪造Master发消息给Ghost,那么Master发消息前就得先对机密内容进行签名。为了进行加密以及通信,人们发明了很多公开的算法,对称与非对称算法等。常见的加密方式有RSA, AES等算法。对于选择加密算法,一个常识就是使用公开的算法。一方面是这些算法经过实践检验,另一方面对于破译难度和破译条件破译时间都有预估。Python良好的生态,对于加密解密技术都有成熟的第三方库。大名鼎鼎的M2Crypto和Pycrypto,前者非常容易使用,可是安装却非常头疼,不同的系统依赖软件的版本还有影响。后者则比较方面,直接使用pip安装即可。接下来我们就先讲解今天要用到大名鼎鼎的RSA算法的原理。
第一步,随机选择两个不相等的质数p和q,如61和53。实际应用中,这两个质数越大,就越难破解。
第二步,计算p和q的乘积n。把61和53相乘,n=61×53=3233。n的长度就是密钥长度。3233写成二进制是110010100001,一共有12位,所以这个密钥就是12位。实际应用中,RSA密钥一般是1024位,重要场合则为2048位。
第三步,计算n的欧拉函数φ(n)。根据公式φ(n) = (p-1)(q-1),φ(3233)等于60×52,即3120。
第四步,随机选择一个整数e,条件是1<e<φ(n),且e与φ(n) 互质。这里我们选择17。实际应用中,常常选择65537。
第五步,计算e对于φ(n)的模反元素d。可以用扩展欧几里得算法求解,此处省略具体过程。算出一组整数解为 (x,y)=(2753,-15),即 d=2753。
第六步,将n和e封装成公钥,n和d封装成私钥。
在上面的例子中,n=3233,e=17,d=2753,所以公钥就是 (3233,17),私钥就是(3233,2753)。
有无可能在已知n和e的情况下,推导出d?如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。可是,大整数的因数分解,是一件非常困难的事情。目前,除了暴力破解,还没有发现别的有效方法。举例来说,你可以对3233进行因式分解(61×53),但是你没法对下面这个整数进行因数分解。
  12301866845301177551304949
  58384962720772853569595334
  79219732245215172640050726
  36575187452021997864693899
  56474942774063845925192557
  32630345373154826850791702
  61221429134616704292143116
  02221240479274737794080665
  351419597459856902143413
它等于这样两个质数的乘积:
  33478071698956898786044169
  84821269081770479498371376
  85689124313889828837938780
  02287614711652531743087737
  814467999489
    ×
  36746043666799590428244633
  79962795263227915816434308
  76426760322838157396665112
  79233373417143396810270092
  798736308917
事实上,这大概是人类已经分解的最大整数(232个十进制位,768个二进制位)。比它更大的因数分解,还没有被报道过,因此目前被破解的最长RSA密钥就是768位。
coding:utf-8import base64from Crypto import Randomfrom Crypto.Hash import SHAfrom Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5from Crypto.PublicKey import RSA#伪随机数生成器random_generator = Random.new().read#rsa算法生成实例rsa = RSA.generate(1024, random_generator)#master的秘钥对的生成private_pem = rsa.exportKey()with open('master-private.pem', 'w') as f:    f.write(private_pem)public_pem = rsa.publickey().exportKey()with open('master-public.pem', 'w') as f:    f.write(public_pem)#rsa算法生成实例rsa = RSA.generate(1024, random_generator)#ghost的秘钥对的生成private_pem = rsa.exportKey()with open('ghost-private.pem', 'w') as f:    f.write(private_pem)public_pem = rsa.publickey().exportKey()with open('ghost-public.pem', 'w') as f:    f.write(public_pem)message = 'hello ghost, this is a plian text'#Master使用Ghost的公钥对明文进行rsa加密with open('ghost-public.pem') as f:    key = f.read()    rsakey = RSA.importKey(key)    cipher = Cipher_pkcs1_v1_5.new(rsakey)    cipher_text = cipher.encrypt(message)    print "encrypted message:"+cipher_text#Ghost使用Ghost的私钥对密文进行rsa解密with open('ghost-private.pem') as f:    key = f.read()    rsakey = RSA.importKey(key)    cipher = Cipher_pkcs1_v1_5.new(rsakey)    text = cipher.decrypt(cipher_text, random_generator)    print "decrypted message:"+text#Master使用Master的私钥对内容进行签名with open('master-private.pem') as f:    key = f.read()    rsakey = RSA.importKey(key)    signer = Signature_pkcs1_v1_5.new(rsakey)    digest = SHA.new()    digest.update(message)    sign = signer.sign(digest)    print "sign:"+sign#Ghost使用Master的公钥对签名进行验证with open('master-public.pem') as f:    key = f.read()    rsakey = RSA.importKey(key)    verifier = Signature_pkcs1_v1_5.new(rsakey)    digest = SHA.new()    digest.update(message)    is_verify = signer.verify(digest, sign)    print is_verify
运行效果如下。



0 0
原创粉丝点击