rsa.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. # This file is dual licensed under the terms of the Apache License, Version
  2. # 2.0, and the BSD License. See the LICENSE file in the root of this repository
  3. # for complete details.
  4. import abc
  5. import typing
  6. from math import gcd
  7. from cryptography import utils
  8. from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
  9. from cryptography.hazmat.backends import _get_backend
  10. from cryptography.hazmat.backends.interfaces import RSABackend
  11. from cryptography.hazmat.primitives import _serialization, hashes
  12. from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding
  13. from cryptography.hazmat.primitives.asymmetric import (
  14. AsymmetricSignatureContext,
  15. AsymmetricVerificationContext,
  16. utils as asym_utils,
  17. )
  18. class RSAPrivateKey(metaclass=abc.ABCMeta):
  19. @abc.abstractmethod
  20. def signer(
  21. self, padding: AsymmetricPadding, algorithm: hashes.HashAlgorithm
  22. ) -> AsymmetricSignatureContext:
  23. """
  24. Returns an AsymmetricSignatureContext used for signing data.
  25. """
  26. @abc.abstractmethod
  27. def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes:
  28. """
  29. Decrypts the provided ciphertext.
  30. """
  31. @abc.abstractproperty
  32. def key_size(self) -> int:
  33. """
  34. The bit length of the public modulus.
  35. """
  36. @abc.abstractmethod
  37. def public_key(self) -> "RSAPublicKey":
  38. """
  39. The RSAPublicKey associated with this private key.
  40. """
  41. @abc.abstractmethod
  42. def sign(
  43. self,
  44. data: bytes,
  45. padding: AsymmetricPadding,
  46. algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
  47. ) -> bytes:
  48. """
  49. Signs the data.
  50. """
  51. @abc.abstractmethod
  52. def private_numbers(self) -> "RSAPrivateNumbers":
  53. """
  54. Returns an RSAPrivateNumbers.
  55. """
  56. @abc.abstractmethod
  57. def private_bytes(
  58. self,
  59. encoding: _serialization.Encoding,
  60. format: _serialization.PrivateFormat,
  61. encryption_algorithm: _serialization.KeySerializationEncryption,
  62. ) -> bytes:
  63. """
  64. Returns the key serialized as bytes.
  65. """
  66. RSAPrivateKeyWithSerialization = RSAPrivateKey
  67. class RSAPublicKey(metaclass=abc.ABCMeta):
  68. @abc.abstractmethod
  69. def verifier(
  70. self,
  71. signature: bytes,
  72. padding: AsymmetricPadding,
  73. algorithm: hashes.HashAlgorithm,
  74. ) -> AsymmetricVerificationContext:
  75. """
  76. Returns an AsymmetricVerificationContext used for verifying signatures.
  77. """
  78. @abc.abstractmethod
  79. def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes:
  80. """
  81. Encrypts the given plaintext.
  82. """
  83. @abc.abstractproperty
  84. def key_size(self) -> int:
  85. """
  86. The bit length of the public modulus.
  87. """
  88. @abc.abstractmethod
  89. def public_numbers(self) -> "RSAPublicNumbers":
  90. """
  91. Returns an RSAPublicNumbers
  92. """
  93. @abc.abstractmethod
  94. def public_bytes(
  95. self,
  96. encoding: _serialization.Encoding,
  97. format: _serialization.PublicFormat,
  98. ) -> bytes:
  99. """
  100. Returns the key serialized as bytes.
  101. """
  102. @abc.abstractmethod
  103. def verify(
  104. self,
  105. signature: bytes,
  106. data: bytes,
  107. padding: AsymmetricPadding,
  108. algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
  109. ) -> None:
  110. """
  111. Verifies the signature of the data.
  112. """
  113. @abc.abstractmethod
  114. def recover_data_from_signature(
  115. self,
  116. signature: bytes,
  117. padding: AsymmetricPadding,
  118. algorithm: typing.Optional[hashes.HashAlgorithm],
  119. ) -> bytes:
  120. """
  121. Recovers the original data from the signature.
  122. """
  123. RSAPublicKeyWithSerialization = RSAPublicKey
  124. def generate_private_key(
  125. public_exponent: int, key_size: int, backend=None
  126. ) -> RSAPrivateKey:
  127. backend = _get_backend(backend)
  128. if not isinstance(backend, RSABackend):
  129. raise UnsupportedAlgorithm(
  130. "Backend object does not implement RSABackend.",
  131. _Reasons.BACKEND_MISSING_INTERFACE,
  132. )
  133. _verify_rsa_parameters(public_exponent, key_size)
  134. return backend.generate_rsa_private_key(public_exponent, key_size)
  135. def _verify_rsa_parameters(public_exponent: int, key_size: int) -> None:
  136. if public_exponent not in (3, 65537):
  137. raise ValueError(
  138. "public_exponent must be either 3 (for legacy compatibility) or "
  139. "65537. Almost everyone should choose 65537 here!"
  140. )
  141. if key_size < 512:
  142. raise ValueError("key_size must be at least 512-bits.")
  143. def _check_private_key_components(
  144. p: int,
  145. q: int,
  146. private_exponent: int,
  147. dmp1: int,
  148. dmq1: int,
  149. iqmp: int,
  150. public_exponent: int,
  151. modulus: int,
  152. ) -> None:
  153. if modulus < 3:
  154. raise ValueError("modulus must be >= 3.")
  155. if p >= modulus:
  156. raise ValueError("p must be < modulus.")
  157. if q >= modulus:
  158. raise ValueError("q must be < modulus.")
  159. if dmp1 >= modulus:
  160. raise ValueError("dmp1 must be < modulus.")
  161. if dmq1 >= modulus:
  162. raise ValueError("dmq1 must be < modulus.")
  163. if iqmp >= modulus:
  164. raise ValueError("iqmp must be < modulus.")
  165. if private_exponent >= modulus:
  166. raise ValueError("private_exponent must be < modulus.")
  167. if public_exponent < 3 or public_exponent >= modulus:
  168. raise ValueError("public_exponent must be >= 3 and < modulus.")
  169. if public_exponent & 1 == 0:
  170. raise ValueError("public_exponent must be odd.")
  171. if dmp1 & 1 == 0:
  172. raise ValueError("dmp1 must be odd.")
  173. if dmq1 & 1 == 0:
  174. raise ValueError("dmq1 must be odd.")
  175. if p * q != modulus:
  176. raise ValueError("p*q must equal modulus.")
  177. def _check_public_key_components(e: int, n: int) -> None:
  178. if n < 3:
  179. raise ValueError("n must be >= 3.")
  180. if e < 3 or e >= n:
  181. raise ValueError("e must be >= 3 and < n.")
  182. if e & 1 == 0:
  183. raise ValueError("e must be odd.")
  184. def _modinv(e: int, m: int) -> int:
  185. """
  186. Modular Multiplicative Inverse. Returns x such that: (x*e) mod m == 1
  187. """
  188. x1, x2 = 1, 0
  189. a, b = e, m
  190. while b > 0:
  191. q, r = divmod(a, b)
  192. xn = x1 - q * x2
  193. a, b, x1, x2 = b, r, x2, xn
  194. return x1 % m
  195. def rsa_crt_iqmp(p: int, q: int) -> int:
  196. """
  197. Compute the CRT (q ** -1) % p value from RSA primes p and q.
  198. """
  199. return _modinv(q, p)
  200. def rsa_crt_dmp1(private_exponent: int, p: int) -> int:
  201. """
  202. Compute the CRT private_exponent % (p - 1) value from the RSA
  203. private_exponent (d) and p.
  204. """
  205. return private_exponent % (p - 1)
  206. def rsa_crt_dmq1(private_exponent: int, q: int) -> int:
  207. """
  208. Compute the CRT private_exponent % (q - 1) value from the RSA
  209. private_exponent (d) and q.
  210. """
  211. return private_exponent % (q - 1)
  212. # Controls the number of iterations rsa_recover_prime_factors will perform
  213. # to obtain the prime factors. Each iteration increments by 2 so the actual
  214. # maximum attempts is half this number.
  215. _MAX_RECOVERY_ATTEMPTS = 1000
  216. def rsa_recover_prime_factors(
  217. n: int, e: int, d: int
  218. ) -> typing.Tuple[int, int]:
  219. """
  220. Compute factors p and q from the private exponent d. We assume that n has
  221. no more than two factors. This function is adapted from code in PyCrypto.
  222. """
  223. # See 8.2.2(i) in Handbook of Applied Cryptography.
  224. ktot = d * e - 1
  225. # The quantity d*e-1 is a multiple of phi(n), even,
  226. # and can be represented as t*2^s.
  227. t = ktot
  228. while t % 2 == 0:
  229. t = t // 2
  230. # Cycle through all multiplicative inverses in Zn.
  231. # The algorithm is non-deterministic, but there is a 50% chance
  232. # any candidate a leads to successful factoring.
  233. # See "Digitalized Signatures and Public Key Functions as Intractable
  234. # as Factorization", M. Rabin, 1979
  235. spotted = False
  236. a = 2
  237. while not spotted and a < _MAX_RECOVERY_ATTEMPTS:
  238. k = t
  239. # Cycle through all values a^{t*2^i}=a^k
  240. while k < ktot:
  241. cand = pow(a, k, n)
  242. # Check if a^k is a non-trivial root of unity (mod n)
  243. if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1:
  244. # We have found a number such that (cand-1)(cand+1)=0 (mod n).
  245. # Either of the terms divides n.
  246. p = gcd(cand + 1, n)
  247. spotted = True
  248. break
  249. k *= 2
  250. # This value was not any good... let's try another!
  251. a += 2
  252. if not spotted:
  253. raise ValueError("Unable to compute factors p and q from exponent d.")
  254. # Found !
  255. q, r = divmod(n, p)
  256. assert r == 0
  257. p, q = sorted((p, q), reverse=True)
  258. return (p, q)
  259. class RSAPrivateNumbers(object):
  260. def __init__(
  261. self,
  262. p: int,
  263. q: int,
  264. d: int,
  265. dmp1: int,
  266. dmq1: int,
  267. iqmp: int,
  268. public_numbers: "RSAPublicNumbers",
  269. ):
  270. if (
  271. not isinstance(p, int)
  272. or not isinstance(q, int)
  273. or not isinstance(d, int)
  274. or not isinstance(dmp1, int)
  275. or not isinstance(dmq1, int)
  276. or not isinstance(iqmp, int)
  277. ):
  278. raise TypeError(
  279. "RSAPrivateNumbers p, q, d, dmp1, dmq1, iqmp arguments must"
  280. " all be an integers."
  281. )
  282. if not isinstance(public_numbers, RSAPublicNumbers):
  283. raise TypeError(
  284. "RSAPrivateNumbers public_numbers must be an RSAPublicNumbers"
  285. " instance."
  286. )
  287. self._p = p
  288. self._q = q
  289. self._d = d
  290. self._dmp1 = dmp1
  291. self._dmq1 = dmq1
  292. self._iqmp = iqmp
  293. self._public_numbers = public_numbers
  294. p = utils.read_only_property("_p")
  295. q = utils.read_only_property("_q")
  296. d = utils.read_only_property("_d")
  297. dmp1 = utils.read_only_property("_dmp1")
  298. dmq1 = utils.read_only_property("_dmq1")
  299. iqmp = utils.read_only_property("_iqmp")
  300. public_numbers = utils.read_only_property("_public_numbers")
  301. def private_key(self, backend=None) -> RSAPrivateKey:
  302. backend = _get_backend(backend)
  303. return backend.load_rsa_private_numbers(self)
  304. def __eq__(self, other):
  305. if not isinstance(other, RSAPrivateNumbers):
  306. return NotImplemented
  307. return (
  308. self.p == other.p
  309. and self.q == other.q
  310. and self.d == other.d
  311. and self.dmp1 == other.dmp1
  312. and self.dmq1 == other.dmq1
  313. and self.iqmp == other.iqmp
  314. and self.public_numbers == other.public_numbers
  315. )
  316. def __ne__(self, other):
  317. return not self == other
  318. def __hash__(self):
  319. return hash(
  320. (
  321. self.p,
  322. self.q,
  323. self.d,
  324. self.dmp1,
  325. self.dmq1,
  326. self.iqmp,
  327. self.public_numbers,
  328. )
  329. )
  330. class RSAPublicNumbers(object):
  331. def __init__(self, e: int, n: int):
  332. if not isinstance(e, int) or not isinstance(n, int):
  333. raise TypeError("RSAPublicNumbers arguments must be integers.")
  334. self._e = e
  335. self._n = n
  336. e = utils.read_only_property("_e")
  337. n = utils.read_only_property("_n")
  338. def public_key(self, backend=None) -> RSAPublicKey:
  339. backend = _get_backend(backend)
  340. return backend.load_rsa_public_numbers(self)
  341. def __repr__(self):
  342. return "<RSAPublicNumbers(e={0.e}, n={0.n})>".format(self)
  343. def __eq__(self, other):
  344. if not isinstance(other, RSAPublicNumbers):
  345. return NotImplemented
  346. return self.e == other.e and self.n == other.n
  347. def __ne__(self, other):
  348. return not self == other
  349. def __hash__(self):
  350. return hash((self.e, self.n))