test_pkcs1_15.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # -*- coding: utf-8 -*-
  2. #
  3. # SelfTest/Cipher/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 encryption
  4. #
  5. # ===================================================================
  6. # The contents of this file are dedicated to the public domain. To
  7. # the extent that dedication to the public domain is not available,
  8. # everyone is granted a worldwide, perpetual, royalty-free,
  9. # non-exclusive license to exercise all rights associated with the
  10. # contents of this file for any purpose whatsoever.
  11. # No rights are reserved.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  17. # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18. # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. # SOFTWARE.
  21. # ===================================================================
  22. __revision__ = "$Id$"
  23. import unittest
  24. import sys
  25. from Crypto.PublicKey import RSA
  26. from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
  27. from Crypto import Random
  28. from Crypto.Cipher import PKCS1_v1_5 as PKCS
  29. from Crypto.Util.py3compat import *
  30. def rws(t):
  31. """Remove white spaces, tabs, and new lines from a string"""
  32. for c in ['\n', '\t', ' ']:
  33. t = t.replace(c,'')
  34. return t
  35. def t2b(t):
  36. """Convert a text string with bytes in hex form to a byte string"""
  37. clean = b(rws(t))
  38. if len(clean)%2 == 1:
  39. print clean
  40. raise ValueError("Even number of characters expected")
  41. return a2b_hex(clean)
  42. class PKCS1_15_Tests(unittest.TestCase):
  43. def setUp(self):
  44. self.rng = Random.new().read
  45. self.key1024 = RSA.generate(1024, self.rng)
  46. # List of tuples with test data for PKCS#1 v1.5.
  47. # Each tuple is made up by:
  48. # Item #0: dictionary with RSA key component, or key to import
  49. # Item #1: plaintext
  50. # Item #2: ciphertext
  51. # Item #3: random data
  52. _testData = (
  53. #
  54. # Generated with openssl 0.9.8o
  55. #
  56. (
  57. # Private key
  58. '''-----BEGIN RSA PRIVATE KEY-----
  59. MIICXAIBAAKBgQDAiAnvIAOvqVwJTaYzsKnefZftgtXGE2hPJppGsWl78yz9jeXY
  60. W/FxX/gTPURArNhdnhP6n3p2ZaDIBrO2zizbgIXs0IsljTTcr4vnI8fMXzyNUOjA
  61. zP3nzMqZDZK6757XQAobOssMkBFqRWwilT/3DsBhRpl3iMUhF+wvpTSHewIDAQAB
  62. AoGAC4HV/inOrpgTvSab8Wj0riyZgQOZ3U3ZpSlsfR8ra9Ib9Uee3jCYnKscu6Gk
  63. y6zI/cdt8EPJ4PuwAWSNJzbpbVaDvUq25OD+CX8/uRT08yBS4J8TzBitZJTD4lS7
  64. atdTnKT0Wmwk+u8tDbhvMKwnUHdJLcuIsycts9rwJVapUtkCQQDvDpx2JMun0YKG
  65. uUttjmL8oJ3U0m3ZvMdVwBecA0eebZb1l2J5PvI3EJD97eKe91Nsw8T3lwpoN40k
  66. IocSVDklAkEAzi1HLHE6EzVPOe5+Y0kGvrIYRRhncOb72vCvBZvD6wLZpQgqo6c4
  67. d3XHFBBQWA6xcvQb5w+VVEJZzw64y25sHwJBAMYReRl6SzL0qA0wIYrYWrOt8JeQ
  68. 8mthulcWHXmqTgC6FEXP9Es5GD7/fuKl4wqLKZgIbH4nqvvGay7xXLCXD/ECQH9a
  69. 1JYNMtRen5unSAbIOxRcKkWz92F0LKpm9ZW/S9vFHO+mBcClMGoKJHiuQxLBsLbT
  70. NtEZfSJZAeS2sUtn3/0CQDb2M2zNBTF8LlM0nxmh0k9VGm5TVIyBEMcipmvOgqIs
  71. HKukWBcq9f/UOmS0oEhai/6g+Uf7VHJdWaeO5LzuvwU=
  72. -----END RSA PRIVATE KEY-----''',
  73. # Plaintext
  74. '''THIS IS PLAINTEXT\x0A''',
  75. # Ciphertext
  76. '''3f dc fd 3c cd 5c 9b 12 af 65 32 e3 f7 d0 da 36
  77. 8f 8f d9 e3 13 1c 7f c8 b3 f9 c1 08 e4 eb 79 9c
  78. 91 89 1f 96 3b 94 77 61 99 a4 b1 ee 5d e6 17 c9
  79. 5d 0a b5 63 52 0a eb 00 45 38 2a fb b0 71 3d 11
  80. f7 a1 9e a7 69 b3 af 61 c0 bb 04 5b 5d 4b 27 44
  81. 1f 5b 97 89 ba 6a 08 95 ee 4f a2 eb 56 64 e5 0f
  82. da 7c f9 9a 61 61 06 62 ed a0 bc 5f aa 6c 31 78
  83. 70 28 1a bb 98 3c e3 6a 60 3c d1 0b 0f 5a f4 75''',
  84. # Random data
  85. '''eb d7 7d 86 a4 35 23 a3 54 7e 02 0b 42 1d
  86. 61 6c af 67 b8 4e 17 56 80 66 36 04 64 34 26 8a
  87. 47 dd 44 b3 1a b2 17 60 f4 91 2e e2 b5 95 64 cc
  88. f9 da c8 70 94 54 86 4c ef 5b 08 7d 18 c4 ab 8d
  89. 04 06 33 8f ca 15 5f 52 60 8a a1 0c f5 08 b5 4c
  90. bb 99 b8 94 25 04 9c e6 01 75 e6 f9 63 7a 65 61
  91. 13 8a a7 47 77 81 ae 0d b8 2c 4d 50 a5'''
  92. ),
  93. )
  94. def testEncrypt1(self):
  95. for test in self._testData:
  96. # Build the key
  97. key = RSA.importKey(test[0])
  98. # RNG that takes its random numbers from a pool given
  99. # at initialization
  100. class randGen:
  101. def __init__(self, data):
  102. self.data = data
  103. self.idx = 0
  104. def __call__(self, N):
  105. r = self.data[self.idx:N]
  106. self.idx += N
  107. return r
  108. # The real test
  109. key._randfunc = randGen(t2b(test[3]))
  110. cipher = PKCS.new(key)
  111. ct = cipher.encrypt(b(test[1]))
  112. self.assertEqual(ct, t2b(test[2]))
  113. def testEncrypt2(self):
  114. # Verify that encryption fail if plaintext is too long
  115. pt = '\x00'*(128-11+1)
  116. cipher = PKCS.new(self.key1024)
  117. self.assertRaises(ValueError, cipher.encrypt, pt)
  118. def testVerify1(self):
  119. for test in self._testData:
  120. # Build the key
  121. key = RSA.importKey(test[0])
  122. # The real test
  123. cipher = PKCS.new(key)
  124. pt = cipher.decrypt(t2b(test[2]), "---")
  125. self.assertEqual(pt, b(test[1]))
  126. def testVerify2(self):
  127. # Verify that decryption fails if ciphertext is not as long as
  128. # RSA modulus
  129. cipher = PKCS.new(self.key1024)
  130. self.assertRaises(ValueError, cipher.decrypt, '\x00'*127, "---")
  131. self.assertRaises(ValueError, cipher.decrypt, '\x00'*129, "---")
  132. # Verify that decryption fails if there are less then 8 non-zero padding
  133. # bytes
  134. pt = b('\x00\x02' + '\xFF'*7 + '\x00' + '\x45'*118)
  135. ct = self.key1024.encrypt(pt, 0)[0]
  136. ct = b('\x00'*(128-len(ct))) + ct
  137. self.assertEqual("---", cipher.decrypt(ct, "---"))
  138. def testEncryptVerify1(self):
  139. # Encrypt/Verify messages of length [0..RSAlen-11]
  140. # and therefore padding [8..117]
  141. for pt_len in xrange(0,128-11+1):
  142. pt = self.rng(pt_len)
  143. cipher = PKCS.new(self.key1024)
  144. ct = cipher.encrypt(pt)
  145. pt2 = cipher.decrypt(ct, "---")
  146. self.assertEqual(pt,pt2)
  147. def get_tests(config={}):
  148. tests = []
  149. tests += list_test_cases(PKCS1_15_Tests)
  150. return tests
  151. if __name__ == '__main__':
  152. suite = lambda: unittest.TestSuite(get_tests())
  153. unittest.main(defaultTest='suite')
  154. # vim:set ts=4 sw=4 sts=4 expandtab: