程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-06(2)

python3 + 官方库rsa 实现加密,解密,签名

发布于2019-08-07 10:25     阅读(1042)     评论(0)     点赞(1)     收藏(5)


0x00 前言

学校网络安全实验,虽然我对密码学真的不感冒,但是我们学院就是这么特别,网络工程也要学密码学,而且是几个学期反复教相同的东西,没错,就是你(XD university)。原理部分就下次再写了。

0x01 实验要求

实验要求1
给定素数p和q,公钥e,计算d
p=11; q=13; e=11; d=??
p=17; q=11; e=7;   d=??
p=5;   q=11; e=3;   d=??
实验要求2
根据自己计算出的公私钥对,以及p, q,设计程序,实现RSA的加密和解密
加密:输入明文、密钥,输出密文
解密:输入密文、密钥,输出明文
实验要求3
根据自己计算出的公私钥对,以及p, q,设计程序,实现RSA的签名和验证
签名:输入消息、密钥,输出签名消息
验证:输入签名消息、密钥,输出原文

0x02 代码与实现

1、计算d

  1. def find_d(e, s):
  2. for d in range(s):
  3. x = (e * d) % s
  4. if x == 1:
  5. return d
  6. if __name__ == '__main__':
  7. p = input("what's your p ?")
  8. q = input("what's your q ?")
  9. e = int(input("what's your e ?"))
  10. s = (int(p)-1) * (int(q)-1)
  11. print(s)
  12. print(find_d(e, s))

2、加密与解密

  1. import rsa
  2. def str2_ascii_int(string1):
  3. xx = ""
  4. for i in string1:
  5. xx = xx + hex(ord(i))[2:]
  6. return int(xx, 16)
  7. def ascii_int2str(num1):
  8. xx = hex(num1)[2:]
  9. i = 0
  10. sign_name = ""
  11. while i < len(xx) / 2:
  12. current_str = xx[2 * i:2 * i + 2]
  13. real = chr(int(current_str, 16))
  14. sign_name = sign_name + real
  15. i = i + 1
  16. return sign_name
  17. def encryption(plaintext, e, n):
  18. cryptotext = pow(plaintext, e) % n
  19. return cryptotext
  20. def decryption(cryptotext, d, n):
  21. plaintext = pow(cryptotext, d) % n
  22. return plaintext
  23. # this part is mainly for signature, in the part, the public key will be used for decryption and the private key will be
  24. # used for encryption, but why? Because the public key is open for everyone, and the private key is just for the owner.
  25. # if you want anyone else to recognize you as xxx, you should offer the other one a signature ,because the signature is
  26. # encrypted by private key, so no one else can get the same signature expect the loss of the private key.
  27. if __name__ == '__main__':
  28. key = rsa.newkeys(32)
  29. n = key[1].n
  30. e = key[1].e
  31. d = key[1].d
  32. plaintext = input("what's your plaintext ?")
  33. print("the plaintext is : ", plaintext)
  34. cryototext = encryption(str2_ascii_int(plaintext), e, n) # 用私钥加密,签名
  35. print("the cryptotext is : ", cryototext)
  36. recognize_name = ascii_int2str(decryption(cryototext, d, n)) # 用公钥解密,验证
  37. print(str(recognize_name))

3、签名与签名验证(我实在想吐槽这个,老师你就不能让我用hash吗,为什么要让我输出原文!!!!

注意:p*q 的值必须大于message的值,否则会出错,也就是说如果你用ascii来做的话,p=17, q = 11 那么message的值必须小于187,所以我这里就只选了一个字母来做验证)

  1. import rsa
  2. def str2_ascii_int(string1):
  3. xx = ""
  4. for i in string1:
  5. xx = xx + hex(ord(i))[2:]
  6. return int(xx, 16)
  7. def ascii_int2str(num1):
  8. xx = hex(num1)[2:]
  9. i = 0
  10. sign_name = ""
  11. while i < len(xx) / 2:
  12. current_str = xx[2 * i:2 * i + 2]
  13. real = chr(int(current_str, 16))
  14. sign_name = sign_name + real
  15. i = i + 1
  16. return sign_name
  17. def encryption(plaintext, e, n):
  18. cryptotext = pow(plaintext, e) % n
  19. return cryptotext
  20. def decryption(cryptotext, d, n):
  21. plaintext = pow(cryptotext, d) % n
  22. return plaintext
  23. # this part is mainly for signature, in the part, the public key will be used for decryption and the private key will be
  24. # used for encryption, but why? Because the public key is open for everyone, and the private key is just for the owner.
  25. # if you want anyone else to recognize you as xxx, you should offer the other one a signature ,because the signature is
  26. # encrypted by private key, so no one else can get the same signature expect the loss of the private key.
  27. if __name__ == '__main__':
  28. key = rsa.newkeys(16) # 这里的生成位数这么低是为了方便我自己计算,作为验证,实际使用请不要这么小
  29. n = key[1].n
  30. e = key[1].e
  31. d = key[1].d
  32. sig_name = input("what's your name ?")
  33. print("your name is : ", sig_name)
  34. signature = encryption(str2_ascii_int(sig_name), d, n) # 用私钥加密,签名
  35. print("the signature is : ", signature)
  36. recognize_name = ascii_int2str(decryption(signature, e, n)) # 用公钥解密,验证
  37. print(str(recognize_name))

 

0x03 注意事项

其实这个实验真的很简单,理论部分你不懂也能做,但是这个实验最恶心的就是python中各种16进制,10进制字符串,消息字符串之间的各种转变,我花时间最多的反而是这个,加解密和签名基本就十几分钟就写好了,当然也是因为这次实验本身不带有密钥生成部分的内容,否则还是要花一些时间的。

0x04 后记与总结

密码学毫无疑问是安全通信中基础中的基础,也是重中之重,然而如何生成安全密钥,管理密钥和防止密钥泄露才是一个工作人员应该注意的点之一。之后有时间会更新关于密钥生成以及密钥管理中的相关内容,有写得不对的地方还请指出。



所属网站分类: 技术文章 > 博客

作者:遥远的她

链接:https://www.pythonheidong.com/blog/article/9818/684f9616047c9a9da760/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

1 0
收藏该文
已收藏

评论内容:(最多支持255个字符)