RSA.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. //
  2. // CryptoSwift
  3. //
  4. // Copyright (C) 2014-2021 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
  5. // This software is provided 'as-is', without any express or implied warranty.
  6. //
  7. // In no event will the authors be held liable for any damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
  10. //
  11. // - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
  12. // - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  13. // - This notice may not be removed or altered from any source or binary distribution.
  14. //
  15. // Foundation is required for `Data` to be found
  16. import Foundation
  17. // Note: The `BigUInt` struct was copied from:
  18. // https://github.com/attaswift/BigInt
  19. // It allows fast calculation for RSA big numbers
  20. public final class RSA: DERCodable {
  21. /// RSA Key Errors
  22. public enum Error: Swift.Error {
  23. /// No private key specified
  24. case noPrivateKey
  25. /// Failed to calculate the inverse e and phi
  26. case invalidInverseNotCoprimes
  27. /// We only support Version 0 RSA keys (we don't support Version 1 introduced in RFC 3447)
  28. case unsupportedRSAVersion
  29. /// Failed to verify primes during initialiization (the provided primes don't reproduce the provided private exponent)
  30. case invalidPrimes
  31. /// We attempted to export a private key without our underlying primes
  32. case noPrimes
  33. /// Unable to calculate the coefficient during a private key import / export
  34. case unableToCalculateCoefficient
  35. /// The signature to verify is of an invalid length
  36. case invalidSignatureLength
  37. /// The message to be signed is of an invalid length
  38. case invalidMessageLengthForSigning
  39. /// The message to be encrypted is of an invalid length
  40. case invalidMessageLengthForEncryption
  41. /// The error thrown when Decryption fails
  42. case invalidDecryption
  43. }
  44. /// RSA Modulus
  45. public let n: BigUInteger
  46. /// RSA Public Exponent
  47. public let e: BigUInteger
  48. /// RSA Private Exponent
  49. public let d: BigUInteger?
  50. /// The size of the modulus, in bits
  51. public let keySize: Int
  52. /// The size of the modulus, in bytes (rounded up to the nearest full byte)
  53. public let keySizeBytes: Int
  54. /// The underlying primes used to generate the Private Exponent
  55. private let primes: (p: BigUInteger, q: BigUInteger)?
  56. /// Initialize with RSA parameters
  57. /// - Parameters:
  58. /// - n: The RSA Modulus
  59. /// - e: The RSA Public Exponent
  60. /// - d: The RSA Private Exponent (or nil if unknown, e.g. if only public key is known)
  61. public init(n: BigUInteger, e: BigUInteger, d: BigUInteger? = nil) {
  62. self.n = n
  63. self.e = e
  64. self.d = d
  65. self.primes = nil
  66. self.keySize = n.bitWidth
  67. self.keySizeBytes = n.byteWidth
  68. }
  69. /// Initialize with RSA parameters
  70. /// - Parameters:
  71. /// - n: The RSA Modulus
  72. /// - e: The RSA Public Exponent
  73. /// - d: The RSA Private Exponent (or nil if unknown, e.g. if only public key is known)
  74. public convenience init(n: Array<UInt8>, e: Array<UInt8>, d: Array<UInt8>? = nil) {
  75. if let d = d {
  76. self.init(n: BigUInteger(Data(n)), e: BigUInteger(Data(e)), d: BigUInteger(Data(d)))
  77. } else {
  78. self.init(n: BigUInteger(Data(n)), e: BigUInteger(Data(e)))
  79. }
  80. }
  81. /// Initialize with a generated key pair
  82. /// - Parameter keySize: The size of the modulus
  83. public convenience init(keySize: Int) throws {
  84. // Generate prime numbers
  85. let p = BigUInteger.generatePrime(keySize / 2)
  86. let q = BigUInteger.generatePrime(keySize / 2)
  87. // Calculate modulus
  88. let n = p * q
  89. // Calculate public and private exponent
  90. let e: BigUInteger = 65537
  91. let phi = (p - 1) * (q - 1)
  92. guard let d = e.inverse(phi) else {
  93. throw RSA.Error.invalidInverseNotCoprimes
  94. }
  95. // Initialize
  96. self.init(n: n, e: e, d: d, p: p, q: q)
  97. }
  98. /// Initialize with RSA parameters
  99. /// - Parameters:
  100. /// - n: The RSA Modulus
  101. /// - e: The RSA Public Exponent
  102. /// - d: The RSA Private Exponent
  103. /// - p: The 1st Prime used to generate the Private Exponent
  104. /// - q: The 2nd Prime used to generate the Private Exponent
  105. private init(n: BigUInteger, e: BigUInteger, d: BigUInteger, p: BigUInteger, q: BigUInteger) {
  106. self.n = n
  107. self.e = e
  108. self.d = d
  109. self.primes = (p, q)
  110. self.keySize = n.bitWidth
  111. self.keySizeBytes = n.byteWidth
  112. }
  113. }
  114. // MARK: BigUInt Extension
  115. internal extension CS.BigUInt {
  116. /// The minimum number of bytes required to represent this integer in binary.
  117. var byteWidth: Int {
  118. let bytes = self.bitWidth / 8
  119. return self.bitWidth % 8 == 0 ? bytes : bytes + 1
  120. }
  121. }
  122. // MARK: DER Initializers (See #892)
  123. extension RSA {
  124. /// Decodes the provided data into a Public RSA Key
  125. ///
  126. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.1)
  127. /// ```
  128. /// =========================
  129. /// RSA PublicKey Structure
  130. /// =========================
  131. ///
  132. /// RSAPublicKey ::= SEQUENCE {
  133. /// modulus INTEGER, -- n
  134. /// publicExponent INTEGER, -- e
  135. /// }
  136. /// ```
  137. internal convenience init(publicDER der: Array<UInt8>) throws {
  138. let asn = try ASN1.Decoder.decode(data: Data(der))
  139. // Enforce the above ASN Structure
  140. guard case .sequence(let params) = asn else { throw DER.Error.invalidDERFormat }
  141. guard params.count == 2 else { throw DER.Error.invalidDERFormat }
  142. guard case .integer(let modulus) = params[0] else { throw DER.Error.invalidDERFormat }
  143. guard case .integer(let publicExponent) = params[1] else { throw DER.Error.invalidDERFormat }
  144. self.init(n: BigUInteger(modulus), e: BigUInteger(publicExponent))
  145. }
  146. /// Decodes the provided data into a Private RSA Key
  147. ///
  148. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.2)
  149. /// ```
  150. /// ==========================
  151. /// RSA PrivateKey Structure
  152. /// ==========================
  153. ///
  154. /// RSAPrivateKey ::= SEQUENCE {
  155. /// version Version,
  156. /// modulus INTEGER, -- n
  157. /// publicExponent INTEGER, -- e
  158. /// privateExponent INTEGER, -- d
  159. /// prime1 INTEGER, -- p
  160. /// prime2 INTEGER, -- q
  161. /// exponent1 INTEGER, -- d mod (p-1)
  162. /// exponent2 INTEGER, -- d mod (q-1)
  163. /// coefficient INTEGER, -- (inverse of q) mod p
  164. /// }
  165. /// ```
  166. internal convenience init(privateDER der: Array<UInt8>) throws {
  167. let asn = try ASN1.Decoder.decode(data: Data(der))
  168. // Enforce the above ASN Structure (do we need to extract and verify the eponents and coefficients?)
  169. guard case .sequence(let params) = asn else { throw DER.Error.invalidDERFormat }
  170. guard params.count == 9 else { throw DER.Error.invalidDERFormat }
  171. guard case .integer(let version) = params[0] else { throw DER.Error.invalidDERFormat }
  172. guard case .integer(let modulus) = params[1] else { throw DER.Error.invalidDERFormat }
  173. guard case .integer(let publicExponent) = params[2] else { throw DER.Error.invalidDERFormat }
  174. guard case .integer(let privateExponent) = params[3] else { throw DER.Error.invalidDERFormat }
  175. guard case .integer(let prime1) = params[4] else { throw DER.Error.invalidDERFormat }
  176. guard case .integer(let prime2) = params[5] else { throw DER.Error.invalidDERFormat }
  177. guard case .integer(let exponent1) = params[6] else { throw DER.Error.invalidDERFormat }
  178. guard case .integer(let exponent2) = params[7] else { throw DER.Error.invalidDERFormat }
  179. guard case .integer(let coefficient) = params[8] else { throw DER.Error.invalidDERFormat }
  180. // We only support version 0x00 == RFC2313 at the moment
  181. // - TODO: Support multiple primes 0x01 version defined in [RFC3447](https://www.rfc-editor.org/rfc/rfc3447#appendix-A.1.2)
  182. guard version == Data(hex: "0x00") else { throw Error.unsupportedRSAVersion }
  183. // Ensure the supplied parameters are correct...
  184. // Calculate modulus
  185. guard BigUInteger(modulus) == BigUInteger(prime1) * BigUInteger(prime2) else { throw Error.invalidPrimes }
  186. // Calculate public and private exponent
  187. let phi = (BigUInteger(prime1) - 1) * (BigUInteger(prime2) - 1)
  188. guard let d = BigUInteger(publicExponent).inverse(phi) else { throw Error.invalidPrimes }
  189. guard BigUInteger(privateExponent) == d else { throw Error.invalidPrimes }
  190. // Ensure the provided coefficient is correct (derived from the primes)
  191. guard let calculatedCoefficient = BigUInteger(prime2).inverse(BigUInteger(prime1)) else { throw RSA.Error.unableToCalculateCoefficient }
  192. guard calculatedCoefficient == BigUInteger(coefficient) else { throw RSA.Error.invalidPrimes }
  193. // Ensure the provided exponents are correct as well
  194. guard (d % (BigUInteger(prime1) - 1)) == BigUInteger(exponent1) else { throw RSA.Error.invalidPrimes }
  195. guard (d % (BigUInteger(prime2) - 1)) == BigUInteger(exponent2) else { throw RSA.Error.invalidPrimes }
  196. // Proceed with regular initialization
  197. self.init(n: BigUInteger(modulus), e: BigUInteger(publicExponent), d: BigUInteger(privateExponent), p: BigUInteger(prime1), q: BigUInteger(prime2))
  198. }
  199. /// Attempts to instantiate an RSA Key when given the ASN1 DER encoded external representation of the Key
  200. ///
  201. /// An example of importing a SecKey RSA key (from Apple's `Security` framework) for use within CryptoSwift
  202. /// ```
  203. /// /// Starting with a SecKey RSA Key
  204. /// let rsaSecKey:SecKey
  205. ///
  206. /// /// Copy the External Representation
  207. /// var externalRepError:Unmanaged<CFError>?
  208. /// guard let externalRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  209. /// /// Failed to copy external representation for RSA SecKey
  210. /// return
  211. /// }
  212. ///
  213. /// /// Instantiate the RSA Key from the raw external representation
  214. /// let rsaKey = try RSA(rawRepresentation: externalRep)
  215. ///
  216. /// /// You now have a CryptoSwift RSA Key
  217. /// // rsaKey.encrypt(...)
  218. /// // rsaKey.decrypt(...)
  219. /// // rsaKey.sign(...)
  220. /// // rsaKey.verify(...)
  221. /// ```
  222. public convenience init(rawRepresentation raw: Data) throws {
  223. do { try self.init(privateDER: raw.bytes) } catch {
  224. try self.init(publicDER: raw.bytes)
  225. }
  226. }
  227. }
  228. // MARK: DER Exports (See #892)
  229. extension RSA {
  230. /// The DER representation of this public key
  231. ///
  232. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.1)
  233. /// ```
  234. /// =========================
  235. /// RSA PublicKey Structure
  236. /// =========================
  237. ///
  238. /// RSAPublicKey ::= SEQUENCE {
  239. /// modulus INTEGER, -- n
  240. /// publicExponent INTEGER -- e
  241. /// }
  242. /// ```
  243. func publicKeyDER() throws -> Array<UInt8> {
  244. let mod = self.n.serialize()
  245. let pubKeyAsnNode: ASN1.Node =
  246. .sequence(nodes: [
  247. .integer(data: DER.i2ospData(x: mod.bytes, size: self.keySizeBytes)),
  248. .integer(data: DER.i2ospData(x: self.e.serialize().bytes, size: 3))
  249. ])
  250. return ASN1.Encoder.encode(pubKeyAsnNode)
  251. }
  252. /// The DER representation of this private key
  253. ///
  254. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.2)
  255. /// ```
  256. /// ==========================
  257. /// RSA PrivateKey Structure
  258. /// ==========================
  259. ///
  260. /// RSAPrivateKey ::= SEQUENCE {
  261. /// version Version,
  262. /// modulus INTEGER, -- n
  263. /// publicExponent INTEGER, -- e
  264. /// privateExponent INTEGER, -- d
  265. /// prime1 INTEGER, -- p
  266. /// prime2 INTEGER, -- q
  267. /// exponent1 INTEGER, -- d mod (p-1)
  268. /// exponent2 INTEGER, -- d mod (q-1)
  269. /// coefficient INTEGER, -- (inverse of q) mod p
  270. /// }
  271. /// ```
  272. func privateKeyDER() throws -> Array<UInt8> {
  273. // Make sure we have a private key
  274. guard let d = d else { throw RSA.Error.noPrivateKey }
  275. // Make sure we have access to our primes
  276. guard let primes = primes else { throw RSA.Error.noPrimes }
  277. // Make sure we can calculate our coefficient (inverse of q mod p)
  278. guard let coefficient = primes.q.inverse(primes.p) else { throw RSA.Error.unableToCalculateCoefficient }
  279. let paramWidth = self.keySizeBytes / 2
  280. // Structure the data (according to RFC2313, version 0x00 RSA Private Key Syntax)
  281. let mod = self.n.serialize()
  282. let privateKeyAsnNode: ASN1.Node =
  283. .sequence(nodes: [
  284. .integer(data: Data(hex: "0x00")),
  285. .integer(data: DER.i2ospData(x: mod.bytes, size: self.keySizeBytes)),
  286. .integer(data: DER.i2ospData(x: self.e.serialize().bytes, size: 3)),
  287. .integer(data: DER.i2ospData(x: d.serialize().bytes, size: self.keySizeBytes)),
  288. .integer(data: DER.i2ospData(x: primes.p.serialize().bytes, size: paramWidth)),
  289. .integer(data: DER.i2ospData(x: primes.q.serialize().bytes, size: paramWidth)),
  290. .integer(data: DER.i2ospData(x: (d % (primes.p - 1)).serialize().bytes, size: paramWidth)),
  291. .integer(data: DER.i2ospData(x: (d % (primes.q - 1)).serialize().bytes, size: paramWidth)),
  292. .integer(data: DER.i2ospData(x: coefficient.serialize().bytes, size: paramWidth))
  293. ])
  294. // Encode and return the data
  295. return ASN1.Encoder.encode(privateKeyAsnNode)
  296. }
  297. /// This method returns the DER encoding of the RSA Key.
  298. ///
  299. /// - Returns: The ASN1 DER Encoding of the Public or Private RSA Key
  300. /// - Note: If the RSA Key is a private key, the private key representation is returned
  301. /// - Note: If the RSA Key is a public key, the public key representation is returned
  302. /// - Note: If you'd like to only export the public DER of an RSA Key call the `publicKeyExternalRepresentation()` method
  303. /// - Note: This method returns the same data as Apple's `SecKeyCopyExternalRepresentation` method.
  304. ///
  305. /// An example of converting a CryptoSwift RSA key to a SecKey RSA key
  306. /// ```
  307. /// /// Starting with a CryptoSwift RSA Key
  308. /// let rsaKey = try RSA(keySize: 1024)
  309. ///
  310. /// /// Define your Keys attributes
  311. /// let attributes: [String:Any] = [
  312. /// kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
  313. /// kSecAttrKeyClass as String: kSecAttrKeyClassPrivate, // or kSecAttrKeyClassPublic
  314. /// kSecAttrKeySizeInBits as String: 1024, // The appropriate bits
  315. /// kSecAttrIsPermanent as String: false
  316. /// ]
  317. /// var error:Unmanaged<CFError>? = nil
  318. /// guard let rsaSecKey = try SecKeyCreateWithData(rsaKey.externalRepresentation() as CFData, attributes as CFDictionary, &error) else {
  319. /// /// Error constructing SecKey from raw key data
  320. /// return
  321. /// }
  322. ///
  323. /// /// You now have an RSA SecKey for use with Apple's Security framework
  324. /// ```
  325. ///
  326. /// An example of converting a SecKey RSA key to a CryptoSwift RSA key
  327. /// ```
  328. /// /// Starting with a SecKey RSA Key
  329. /// let rsaSecKey:SecKey
  330. ///
  331. /// /// Copy External Representation
  332. /// var externalRepError:Unmanaged<CFError>?
  333. /// guard let cfdata = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) else {
  334. /// /// Failed to copy external representation for RSA SecKey
  335. /// return
  336. /// }
  337. ///
  338. /// /// Instantiate the RSA Key from the raw external representation
  339. /// let rsaKey = try RSA(rawRepresentation: cfdata as Data)
  340. ///
  341. /// /// You now have a CryptoSwift RSA Key
  342. /// ```
  343. ///
  344. func externalRepresentation() throws -> Data {
  345. if self.primes != nil {
  346. return try Data(self.privateKeyDER())
  347. } else {
  348. return try Data(self.publicKeyDER())
  349. }
  350. }
  351. }
  352. // MARK: CS.BigUInt extension
  353. extension BigUInteger {
  354. public static func generatePrime(_ width: Int) -> BigUInteger {
  355. // Note: Need to find a better way to generate prime numbers
  356. while true {
  357. var random = BigUInteger.randomInteger(withExactWidth: width)
  358. random |= BigUInteger(1)
  359. if random.isPrime() {
  360. return random
  361. }
  362. }
  363. }
  364. }
  365. // MARK: CustomStringConvertible Conformance
  366. extension RSA: CustomStringConvertible {
  367. public var description: String {
  368. if self.d != nil {
  369. return "CryptoSwift.RSA.PrivateKey<\(self.keySize)>"
  370. } else {
  371. return "CryptoSwift.RSA.PublicKey<\(self.keySize)>"
  372. }
  373. }
  374. }