[关闭]
@iPhan 2017-12-11T14:38:54.000000Z 字数 4706 阅读 498

张一帆15180110001密码学实验_ex6

密码学


第一道题目

题目给了dsa参数,dsa公钥;以及一个签名样例,包括消息的hash‘h_m’以及消息的签名(r, s);同时说明了随机数k的取值为 0 ~ 2^16。数据如下:

  1. p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1
  2. q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b
  3. g = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291
  4. y = 0x84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07bbb283e6633451e535c45513b2d33c99ea17
  5. m = b"""For those that envy a MC it can be hazardous to your health
  6. So be friendly, a matter of life and death, just like a etch-a-sketch"""
  7. h_m = 0xd2d0714f014a9784047eaeccf956520045c45265
  8. r = 548099063082341131477253921760299949438196259240
  9. s = 857042759984254168557880549501802188789837994940
  10. h_k = "0954edd5e0afe5542a4adf012611a91912a3ec16"

因为k的取值空间太小了,2^16 == 65535 ,我们可以穷举k,并判断每一个k对应的x(私钥)的hash是否与给定的hash‘h_k’相同。完整代码如下:

  1. import hashlib
  2. from Crypto.Util.number import *
  3. p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1
  4. q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b
  5. g = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291
  6. y = 0x84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07bbb283e6633451e535c45513b2d33c99ea17
  7. h_m = 0xd2d0714f014a9784047eaeccf956520045c45265
  8. r = 548099063082341131477253921760299949438196259240
  9. s = 857042759984254168557880549501802188789837994940
  10. h_k = "0954edd5e0afe5542a4adf012611a91912a3ec16"
  11. for k in range(pow(2, 16)):
  12. x = ((s * k - h_m) * inverse(r, q)) % q
  13. x = bytes(hex(x)[2:], 'UTF-8')
  14. if hashlib.sha1(x).hexdigest() == h_k:
  15. print(x)
  16. print(k)
  17. break

输出:

  1. 15fb2873d16b3e129ff76d0918fd7ada54659e49
  2. 16575

第二道题目

题目给了一组消息和dsa签名,其中所有的dsa签名共用一组参数。在这些签名中,随机数k被重复的使用了,要求恢复x。

首先判断哪些数据使用了相同的k:判断依据是不同消息的签名r是否相同。找到三组r相同的签名:

  1. 0---8
  2. 1---9
  3. 2---10

然后随便找一组开始恢复k:

  1. l = [
  2. [1267396447369736888040262262183731677867615804316,
  3. 1105520928110492191417703162650245113664610474875, 0xa4db3de27e2db3e5ef085ced2bced91b82e0df19],
  4. [29097472083055673620219739525237952924429516683,
  5. 51241962016175933742870323080382366896234169532, 0xa4db3de27e2db3e5ef085ced2bced91b82e0df19],
  6. [277954141006005142760672187124679727147013405915,
  7. 228998983350752111397582948403934722619745721541, 0x21194f72fe39a80c9c20689b8cf6ce9b0e7e52d4],
  8. [1013310051748123261520038320957902085950122277350,
  9. 1099349585689717635654222811555852075108857446485, 0x1d7aaaa05d2dee2f7dabdc6fa70b6ddab9c051c5],
  10. [203941148183364719753516612269608665183595279549,
  11. 425320991325990345751346113277224109611205133736, 0x6bc188db6e9e6c7d796f7fdd7fa411776d7a9ff],
  12. [502033987625712840101435170279955665681605114553,
  13. 486260321619055468276539425880393574698069264007, 0x5ff4d4e8be2f8aae8a5bfaabf7408bd7628f43c9],
  14. [1133410958677785175751131958546453870649059955513,
  15. 537050122560927032962561247064393639163940220795, 0x7d9abd18bbecdaa93650ecc4da1b9fcae911412],
  16. [559339368782867010304266546527989050544914568162,
  17. 826843595826780327326695197394862356805575316699, 0x88b9e184393408b133efef59fcef85576d69e249],
  18. [1021643638653719618255840562522049391608552714967,
  19. 1105520928110492191417703162650245113664610474875, 0xd22804c4899b522b23eda34d2137cd8cc22b9ce8],
  20. [506591325247687166499867321330657300306462367256,
  21. 51241962016175933742870323080382366896234169532, 0xbc7ec371d951977cba10381da08fe934dea80314],
  22. [458429062067186207052865988429747640462282138703,
  23. 228998983350752111397582948403934722619745721541, 0xd6340bfcda59b6b75b59ca634813d572de800e8f]
  24. ]
  25. d = {
  26. 0: l[0],
  27. 1: l[1],
  28. 2: l[2],
  29. 8: l[8],
  30. 9: l[9],
  31. 10: l[10]
  32. }
  33. k = ((d[0][2] - d[8][2]) * inverse(d[0][0] - d[8][0], q)) % q

然后恢复x,并判断结果是否正确

  1. x0 = ((d[0][0] * k - d[0][2]) * inverse(d[0][1], q)) % q
  2. print(x0)
  3. x8 = ((d[8][0] * k - d[8][2]) * inverse(d[8][1], q)) % q
  4. print(x8)
  5. print(hashlib.sha1(bytes(hex(x0)[2:], 'UTF-8')).hexdigest())

输出:

  1. 1379952329417023174824742221952501647027600451162
  2. 1379952329417023174824742221952501647027600451162
  3. ca8f6f7c66fa362d40760d135b763eb8527d3d52

和题目给出的x的hash对比,符合要求。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注