[关闭]
@2017libin 2019-10-28T08:07:36.000000Z 字数 2561 阅读 68

project for RSA

密码学


简单的描述

  1. 使用随机函数生成一个大整数,介于512bits和1024bits之间。
  2. 使用米勒拉宾算法进行素性测试
  3. 使用快速幂来快速的进行加密解密操作,也就是幂运算取模。
  4. 使用gcd来判断e是否和phin互素
  5. 使用egcd来求d
  6. 使用字典来对实现简单字符串和整数之间的映射
  7. 使用md5来对文件内容进行映射

截图

加密解密.png
签名验证.png

源代码

  1. import random
  2. import hashlib
  3. # return a^b mod n
  4. def QuickPow(a, b, n):
  5. t = 1
  6. tmp = a % n
  7. while b > 0:
  8. if (b & 1):
  9. t = (t * tmp) % n
  10. tmp = tmp * tmp % n
  11. b >>= 1
  12. return t
  13. # 选择一个a来对大整数p的素性测试
  14. def MillerRabin(a, p):
  15. if (a & 1 == 0):
  16. return False
  17. p1 = p - 1
  18. s2 = p1 & -p1 # 找到最右边的1
  19. x = QuickPow(a, p1 // s2, p)
  20. if x == 1 or x == p1:
  21. return True
  22. while s2 > 1:
  23. x = (x * x) % p
  24. if x == 1:
  25. return False
  26. if x == p1:
  27. return True
  28. s2 >>= 1
  29. return False
  30. # 对p进行测试k次
  31. def IsPrime(p, k):
  32. if p == 2 or p == 3:
  33. return True
  34. if p < 2 or (p & 1) == 0:
  35. return False
  36. for i in range(k):
  37. if not MillerRabin(random.randint(2, p - 1), p):
  38. return False
  39. return True
  40. # 获得一个介于512比特和1024比特的大素数
  41. def getBigPrime():
  42. while True:
  43. tmp = random.randint(2 ** 512, 2 ** 1024)
  44. if IsPrime(tmp, 3):
  45. return tmp
  46. # ax + by = d = gcd(a,b), 其中a>b
  47. def Egcd(a, b):
  48. x1, y1, x2, y2 = 1, 0, 0, 1
  49. while (b):
  50. q = a // b
  51. r = a - b * q
  52. tmp_x, tmp_y = x2, y2
  53. x2, y2 = x1 - x2 * q, y1 - y2 * q
  54. x1, y1 = tmp_x, tmp_y
  55. a = b
  56. b = r
  57. return y1
  58. # gcd(a,b)
  59. def Gcd(a, b):
  60. while b > 0:
  61. tmp = a % b
  62. a, b = b, tmp
  63. return a
  64. def EnCode(e, n):
  65. Str = input("请输入明文:")
  66. m = CharToInt(Str)
  67. print("相应的密文是:", QuickPow(m, e, n))
  68. def DeCode(d, n):
  69. c = int(input("请输入密文:"))
  70. m = IntToChar(QuickPow(c, d, n))
  71. print("相应的明文是:", m)
  72. def CharToInt(string):
  73. abc_table = dict()
  74. for i in range(97, 123):
  75. abc_table[chr(i)] = i - 50
  76. abc_table[" "] = 10
  77. abc_table["!"] = 11
  78. print(abc_table)
  79. number = ""
  80. for s in string:
  81. number += str(abc_table[s])
  82. return int(number)
  83. def IntToChar(number):
  84. number_table = dict()
  85. for i in range(97, 123):
  86. number_table[i - 50] = chr(i)
  87. number_table[10] = " "
  88. number_table[11] = "!"
  89. i = 0
  90. Str0 = str(number)
  91. Str = ""
  92. while i < len(Str0):
  93. Str += number_table[int(Str0[i:i + 2])]
  94. i += 2
  95. return Str
  96. # 这里对文本进行hash,一个文本对应着唯一的hash值
  97. def Signature(filename, d, n):
  98. f = open(filename, "r", encoding="utf-8") # 将文本内容进行hash
  99. md5 = hashlib.md5()
  100. md5.update(f.read().encode("utf-8"))
  101. m = int(md5.hexdigest(), 16)
  102. print("对应文件的签名是:", QuickPow(m, d, n))
  103. # 对明文进行hash,然后对密文进行解密
  104. # 进行对比,值相同则验证签名成功
  105. def Validation(filename, signature, e, n):
  106. f = open(filename, "r", encoding="utf-8")
  107. md5 = hashlib.md5()
  108. md5.update(f.read().encode("utf-8"))
  109. m = int(md5.hexdigest(), 16)
  110. m1 = QuickPow(signature, e, n)
  111. if m == m1:
  112. print("验证成功!")
  113. else:
  114. print("验证失败!")
  115. def Main():
  116. p, q = getBigPrime(), getBigPrime() # 选择两个大素数p,q
  117. phin = (p - 1) * (q - 1)
  118. n = p * q
  119. while True: # 随机选择一个e
  120. e = random.randint(0, phin)
  121. if Gcd(phin, e) == 1:
  122. break
  123. d = Egcd(phin, e) # 根据e来构造d
  124. if d < 0:
  125. d += phin
  126. while True: # 用户交互界面
  127. print("请输入相应序号:\n 1. 输入明文加密\n 2. 输入密文解密\n 3.签名 \n 4.验证签名\n 5.离开")
  128. select = input()
  129. if select == "1":
  130. EnCode(e, n)
  131. elif select == "2":
  132. DeCode(d, n)
  133. elif select == "3":
  134. filename = input("请输入文件名: ")
  135. Signature(filename, d, n)
  136. elif select == "4":
  137. filename = input("请输入文件名: ")
  138. signature = int(input("请输入签名: "))
  139. Validation(filename, signature, e, n)
  140. elif select == "5":
  141. break
  142. else:
  143. print("输入有误,请重新输入!")
  144. if __name__ == '__main__':
  145. Main()
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注