RSA.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. //
  2. // CryptoSwift
  3. //
  4. // Copyright (C) 2014-2025 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. public 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. try 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. public init(n: BigUInteger, e: BigUInteger, d: BigUInteger, p: BigUInteger, q: BigUInteger) throws {
  106. // Ensure the supplied parameters are correct...
  107. // Calculate modulus
  108. guard n == p * q else { throw Error.invalidPrimes }
  109. // Calculate public and private exponent
  110. let phi = (p - 1) * (q - 1)
  111. guard d == e.inverse(phi) else { throw Error.invalidPrimes }
  112. // Regular initialization
  113. self.n = n
  114. self.e = e
  115. self.d = d
  116. self.primes = (p, q)
  117. self.keySize = n.bitWidth
  118. self.keySizeBytes = n.byteWidth
  119. }
  120. }
  121. // MARK: BigUInt Extension
  122. internal extension CS.BigUInt {
  123. /// The minimum number of bytes required to represent this integer in binary.
  124. var byteWidth: Int {
  125. let bytes = self.bitWidth / 8
  126. return self.bitWidth % 8 == 0 ? bytes : bytes + 1
  127. }
  128. }
  129. // MARK: DER Initializers (See #892)
  130. extension RSA {
  131. /// Decodes the provided data into a Public RSA Key
  132. ///
  133. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.1)
  134. /// ```
  135. /// =========================
  136. /// RSA PublicKey Structure
  137. /// =========================
  138. ///
  139. /// RSAPublicKey ::= SEQUENCE {
  140. /// modulus INTEGER, -- n
  141. /// publicExponent INTEGER, -- e
  142. /// }
  143. /// ```
  144. internal convenience init(publicDER der: Array<UInt8>) throws {
  145. let asn = try ASN1.Decoder.decode(data: Data(der))
  146. // Enforce the above ASN Structure
  147. guard case .sequence(let params) = asn else { throw DER.Error.invalidDERFormat }
  148. guard params.count == 2 else { throw DER.Error.invalidDERFormat }
  149. guard case .integer(let modulus) = params[0] else { throw DER.Error.invalidDERFormat }
  150. guard case .integer(let publicExponent) = params[1] else { throw DER.Error.invalidDERFormat }
  151. self.init(n: BigUInteger(modulus), e: BigUInteger(publicExponent))
  152. }
  153. /// Decodes the provided data into a Private RSA Key
  154. ///
  155. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.2)
  156. /// ```
  157. /// ==========================
  158. /// RSA PrivateKey Structure
  159. /// ==========================
  160. ///
  161. /// RSAPrivateKey ::= SEQUENCE {
  162. /// version Version,
  163. /// modulus INTEGER, -- n
  164. /// publicExponent INTEGER, -- e
  165. /// privateExponent INTEGER, -- d
  166. /// prime1 INTEGER, -- p
  167. /// prime2 INTEGER, -- q
  168. /// exponent1 INTEGER, -- d mod (p-1)
  169. /// exponent2 INTEGER, -- d mod (q-1)
  170. /// coefficient INTEGER, -- (inverse of q) mod p
  171. /// }
  172. /// ```
  173. internal convenience init(privateDER der: Array<UInt8>) throws {
  174. let asn = try ASN1.Decoder.decode(data: Data(der))
  175. // Enforce the above ASN Structure (do we need to extract and verify the eponents and coefficients?)
  176. guard case .sequence(let params) = asn else { throw DER.Error.invalidDERFormat }
  177. guard params.count == 9 else { throw DER.Error.invalidDERFormat }
  178. guard case .integer(let version) = params[0] else { throw DER.Error.invalidDERFormat }
  179. guard case .integer(let modulus) = params[1] else { throw DER.Error.invalidDERFormat }
  180. guard case .integer(let publicExponent) = params[2] else { throw DER.Error.invalidDERFormat }
  181. guard case .integer(let privateExponent) = params[3] else { throw DER.Error.invalidDERFormat }
  182. guard case .integer(let prime1) = params[4] else { throw DER.Error.invalidDERFormat }
  183. guard case .integer(let prime2) = params[5] else { throw DER.Error.invalidDERFormat }
  184. guard case .integer(let exponent1) = params[6] else { throw DER.Error.invalidDERFormat }
  185. guard case .integer(let exponent2) = params[7] else { throw DER.Error.invalidDERFormat }
  186. guard case .integer(let coefficient) = params[8] else { throw DER.Error.invalidDERFormat }
  187. // We only support version 0x00 == RFC2313 at the moment
  188. // - TODO: Support multiple primes 0x01 version defined in [RFC3447](https://www.rfc-editor.org/rfc/rfc3447#appendix-A.1.2)
  189. guard version == Data(hex: "0x00") else { throw Error.unsupportedRSAVersion }
  190. // Calculate public and private exponent
  191. let phi = (BigUInteger(prime1) - 1) * (BigUInteger(prime2) - 1)
  192. guard let d = BigUInteger(publicExponent).inverse(phi) else { throw Error.invalidPrimes }
  193. guard BigUInteger(privateExponent) == d else { throw Error.invalidPrimes }
  194. // Ensure the provided coefficient is correct (derived from the primes)
  195. guard let calculatedCoefficient = BigUInteger(prime2).inverse(BigUInteger(prime1)) else { throw RSA.Error.unableToCalculateCoefficient }
  196. guard calculatedCoefficient == BigUInteger(coefficient) else { throw RSA.Error.invalidPrimes }
  197. // Ensure the provided exponents are correct as well
  198. guard (d % (BigUInteger(prime1) - 1)) == BigUInteger(exponent1) else { throw RSA.Error.invalidPrimes }
  199. guard (d % (BigUInteger(prime2) - 1)) == BigUInteger(exponent2) else { throw RSA.Error.invalidPrimes }
  200. // Proceed with regular initialization
  201. try self.init(n: BigUInteger(modulus), e: BigUInteger(publicExponent), d: BigUInteger(privateExponent), p: BigUInteger(prime1), q: BigUInteger(prime2))
  202. }
  203. /// Attempts to instantiate an RSA Key when given the ASN1 DER encoded external representation of the Key
  204. ///
  205. /// An example of importing a SecKey RSA key (from Apple's `Security` framework) for use within CryptoSwift
  206. /// ```
  207. /// /// Starting with a SecKey RSA Key
  208. /// let rsaSecKey:SecKey
  209. ///
  210. /// /// Copy the External Representation
  211. /// var externalRepError:Unmanaged<CFError>?
  212. /// guard let externalRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  213. /// /// Failed to copy external representation for RSA SecKey
  214. /// return
  215. /// }
  216. ///
  217. /// /// Instantiate the RSA Key from the raw external representation
  218. /// let rsaKey = try RSA(rawRepresentation: externalRep)
  219. ///
  220. /// /// You now have a CryptoSwift RSA Key
  221. /// // rsaKey.encrypt(...)
  222. /// // rsaKey.decrypt(...)
  223. /// // rsaKey.sign(...)
  224. /// // rsaKey.verify(...)
  225. /// ```
  226. public convenience init(rawRepresentation raw: Data) throws {
  227. do { try self.init(privateDER: raw.bytes) } catch {
  228. try self.init(publicDER: raw.bytes)
  229. }
  230. }
  231. }
  232. // MARK: DER Exports (See #892)
  233. extension RSA {
  234. /// The DER representation of this public key
  235. ///
  236. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.1)
  237. /// ```
  238. /// =========================
  239. /// RSA PublicKey Structure
  240. /// =========================
  241. ///
  242. /// RSAPublicKey ::= SEQUENCE {
  243. /// modulus INTEGER, -- n
  244. /// publicExponent INTEGER -- e
  245. /// }
  246. /// ```
  247. func publicKeyDER() throws -> Array<UInt8> {
  248. let mod = self.n.serialize()
  249. let exp = self.e.serialize()
  250. let pubKeyAsnNode: ASN1.Node =
  251. .sequence(nodes: [
  252. .integer(data: DER.i2ospData(x: mod.bytes, size: self.keySizeBytes)),
  253. .integer(data: DER.i2ospData(x: exp.bytes, size: exp.bytes.count))
  254. ])
  255. return ASN1.Encoder.encode(pubKeyAsnNode)
  256. }
  257. /// The DER representation of this private key
  258. ///
  259. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.2)
  260. /// ```
  261. /// ==========================
  262. /// RSA PrivateKey Structure
  263. /// ==========================
  264. ///
  265. /// RSAPrivateKey ::= SEQUENCE {
  266. /// version Version,
  267. /// modulus INTEGER, -- n
  268. /// publicExponent INTEGER, -- e
  269. /// privateExponent INTEGER, -- d
  270. /// prime1 INTEGER, -- p
  271. /// prime2 INTEGER, -- q
  272. /// exponent1 INTEGER, -- d mod (p-1)
  273. /// exponent2 INTEGER, -- d mod (q-1)
  274. /// coefficient INTEGER, -- (inverse of q) mod p
  275. /// }
  276. /// ```
  277. func privateKeyDER() throws -> Array<UInt8> {
  278. // Make sure we have a private key
  279. guard let d = d else { throw RSA.Error.noPrivateKey }
  280. // Make sure we have access to our primes
  281. guard let primes = primes else { throw RSA.Error.noPrimes }
  282. // Make sure we can calculate our coefficient (inverse of q mod p)
  283. guard let coefficient = primes.q.inverse(primes.p) else { throw RSA.Error.unableToCalculateCoefficient }
  284. let paramWidth = self.keySizeBytes / 2
  285. // Structure the data (according to RFC2313, version 0x00 RSA Private Key Syntax)
  286. let mod = self.n.serialize()
  287. let privateKeyAsnNode: ASN1.Node =
  288. .sequence(nodes: [
  289. .integer(data: Data(hex: "0x00")),
  290. .integer(data: DER.i2ospData(x: mod.bytes, size: self.keySizeBytes)),
  291. .integer(data: DER.i2ospData(x: self.e.serialize().bytes, size: 3)),
  292. .integer(data: DER.i2ospData(x: d.serialize().bytes, size: self.keySizeBytes)),
  293. .integer(data: DER.i2ospData(x: primes.p.serialize().bytes, size: paramWidth)),
  294. .integer(data: DER.i2ospData(x: primes.q.serialize().bytes, size: paramWidth)),
  295. .integer(data: DER.i2ospData(x: (d % (primes.p - 1)).serialize().bytes, size: paramWidth)),
  296. .integer(data: DER.i2ospData(x: (d % (primes.q - 1)).serialize().bytes, size: paramWidth)),
  297. .integer(data: DER.i2ospData(x: coefficient.serialize().bytes, size: paramWidth))
  298. ])
  299. // Encode and return the data
  300. return ASN1.Encoder.encode(privateKeyAsnNode)
  301. }
  302. /// This method returns the DER encoding of the RSA Key.
  303. ///
  304. /// - Returns: The ASN1 DER Encoding of the Public or Private RSA Key
  305. /// - Note: If the RSA Key is a private key, the private key representation is returned
  306. /// - Note: If the RSA Key is a public key, the public key representation is returned
  307. /// - Note: If you'd like to only export the public DER of an RSA Key call the `publicKeyExternalRepresentation()` method
  308. /// - Note: This method returns the same data as Apple's `SecKeyCopyExternalRepresentation` method.
  309. ///
  310. /// An example of converting a CryptoSwift RSA key to a SecKey RSA key
  311. /// ```
  312. /// /// Starting with a CryptoSwift RSA Key
  313. /// let rsaKey = try RSA(keySize: 1024)
  314. ///
  315. /// /// Define your Keys attributes
  316. /// let attributes: [String:Any] = [
  317. /// kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
  318. /// kSecAttrKeyClass as String: kSecAttrKeyClassPrivate, // or kSecAttrKeyClassPublic
  319. /// kSecAttrKeySizeInBits as String: 1024, // The appropriate bits
  320. /// kSecAttrIsPermanent as String: false
  321. /// ]
  322. /// var error:Unmanaged<CFError>? = nil
  323. /// guard let rsaSecKey = try SecKeyCreateWithData(rsaKey.externalRepresentation() as CFData, attributes as CFDictionary, &error) else {
  324. /// /// Error constructing SecKey from raw key data
  325. /// return
  326. /// }
  327. ///
  328. /// /// You now have an RSA SecKey for use with Apple's Security framework
  329. /// ```
  330. ///
  331. /// An example of converting a SecKey RSA key to a CryptoSwift RSA key
  332. /// ```
  333. /// /// Starting with a SecKey RSA Key
  334. /// let rsaSecKey:SecKey
  335. ///
  336. /// /// Copy External Representation
  337. /// var externalRepError:Unmanaged<CFError>?
  338. /// guard let cfdata = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) else {
  339. /// /// Failed to copy external representation for RSA SecKey
  340. /// return
  341. /// }
  342. ///
  343. /// /// Instantiate the RSA Key from the raw external representation
  344. /// let rsaKey = try RSA(rawRepresentation: cfdata as Data)
  345. ///
  346. /// /// You now have a CryptoSwift RSA Key
  347. /// ```
  348. ///
  349. public func externalRepresentation() throws -> Data {
  350. if self.d != nil {
  351. return try Data(self.privateKeyDER())
  352. } else {
  353. return try Data(self.publicKeyDER())
  354. }
  355. }
  356. public func publicKeyExternalRepresentation() throws -> Data {
  357. return try Data(self.publicKeyDER())
  358. }
  359. }
  360. // MARK: CS.BigUInt extension
  361. extension BigUInteger {
  362. public static func generatePrime(_ width: Int) -> BigUInteger {
  363. // Note: Need to find a better way to generate prime numbers
  364. while true {
  365. var random = BigUInteger.randomInteger(withExactWidth: width)
  366. random |= BigUInteger(1)
  367. if random.isPrime() {
  368. return random
  369. }
  370. }
  371. }
  372. }
  373. // MARK: CustomStringConvertible Conformance
  374. extension RSA: CustomStringConvertible {
  375. public var description: String {
  376. if self.d != nil {
  377. return "CryptoSwift.RSA.PrivateKey<\(self.keySize)>"
  378. } else {
  379. return "CryptoSwift.RSA.PublicKey<\(self.keySize)>"
  380. }
  381. }
  382. }