RSA.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  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 Object Identifier Bytes (rsaEncryption)
  22. static var primaryObjectIdentifier: Array<UInt8> = Array<UInt8>(arrayLiteral: 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01)
  23. /// RSA Secondary Object Identifier Bytes (null)
  24. static var secondaryObjectIdentifier: Array<UInt8>?
  25. public enum Error: Swift.Error {
  26. /// No private key specified
  27. case noPrivateKey
  28. /// Failed to calculate the inverse e and phi
  29. case invalidInverseNotCoprimes
  30. /// We were provided invalid DER data
  31. case invalidDERFormat
  32. /// Failed to verify primes during DER initialiization (the provided primes don't reproduce the provided private exponent)
  33. case invalidPrimes
  34. /// We attempted to export a private key without our underlying primes
  35. case noPrimes
  36. /// Unable to calculate the coefficient during a private key DER export
  37. case unableToCalculateCoefficient
  38. }
  39. /// RSA Modulus
  40. public let n: BigUInteger
  41. /// RSA Public Exponent
  42. public let e: BigUInteger
  43. /// RSA Private Exponent
  44. public let d: BigUInteger?
  45. /// The size of the modulus, in bits
  46. public let keySize: Int
  47. /// The underlying primes used to generate the Private Exponent
  48. private let primes: (p: BigUInteger, q: BigUInteger)?
  49. /// Initialize with RSA parameters
  50. /// - Parameters:
  51. /// - n: The RSA Modulus
  52. /// - e: The RSA Public Exponent
  53. /// - d: The RSA Private Exponent (or nil if unknown, e.g. if only public key is known)
  54. public init(n: BigUInteger, e: BigUInteger, d: BigUInteger? = nil) {
  55. self.n = n
  56. self.e = e
  57. self.d = d
  58. self.primes = nil
  59. self.keySize = n.bitWidth
  60. }
  61. /// Initialize with RSA parameters
  62. /// - Parameters:
  63. /// - n: The RSA Modulus
  64. /// - e: The RSA Public Exponent
  65. /// - d: The RSA Private Exponent (or nil if unknown, e.g. if only public key is known)
  66. public convenience init(n: Array<UInt8>, e: Array<UInt8>, d: Array<UInt8>? = nil) {
  67. if let d = d {
  68. self.init(n: BigUInteger(Data(n)), e: BigUInteger(Data(e)), d: BigUInteger(Data(d)))
  69. } else {
  70. self.init(n: BigUInteger(Data(n)), e: BigUInteger(Data(e)))
  71. }
  72. }
  73. /// Initialize with a generated key pair
  74. /// - Parameter keySize: The size of the modulus
  75. public convenience init(keySize: Int) throws {
  76. // Generate prime numbers
  77. let p = BigUInteger.generatePrime(keySize / 2)
  78. let q = BigUInteger.generatePrime(keySize / 2)
  79. // Calculate modulus
  80. let n = p * q
  81. // Calculate public and private exponent
  82. let e: BigUInteger = 65537
  83. let phi = (p - 1) * (q - 1)
  84. guard let d = e.inverse(phi) else {
  85. throw RSA.Error.invalidInverseNotCoprimes
  86. }
  87. // Initialize
  88. self.init(n: n, e: e, d: d, p: p, q: q)
  89. }
  90. /// Initialize with RSA parameters
  91. /// - Parameters:
  92. /// - n: The RSA Modulus
  93. /// - e: The RSA Public Exponent
  94. /// - d: The RSA Private Exponent
  95. /// - p: The 1st Prime used to generate the Private Exponent
  96. /// - q: The 2nd Prime used to generate the Private Exponent
  97. private init(n: BigUInteger, e: BigUInteger, d: BigUInteger, p: BigUInteger, q: BigUInteger) {
  98. self.n = n
  99. self.e = e
  100. self.d = d
  101. self.primes = (p, q)
  102. self.keySize = n.bitWidth
  103. }
  104. }
  105. // MARK: DER Initializers (See #892)
  106. extension RSA {
  107. /// Decodes the provided data into a Public RSA Key
  108. ///
  109. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.1)
  110. /// ```
  111. /// =========================
  112. /// RSA PublicKey Structure
  113. /// =========================
  114. ///
  115. /// RSAPublicKey ::= SEQUENCE {
  116. /// modulus INTEGER, -- n
  117. /// publicExponent INTEGER, -- e
  118. /// }
  119. /// ```
  120. internal convenience init(publicDER der: Array<UInt8>) throws {
  121. let asn = try ASN1.Decoder.decode(data: Data(der))
  122. // Enforce the above ASN Structure
  123. guard case .sequence(let params) = asn else { throw Error.invalidDERFormat }
  124. guard params.count == 2 else { throw Error.invalidDERFormat }
  125. guard case .integer(let modulus) = params[0] else { throw Error.invalidDERFormat }
  126. guard case .integer(let publicExponent) = params[1] else { throw Error.invalidDERFormat }
  127. self.init(n: BigUInteger(modulus), e: BigUInteger(publicExponent))
  128. }
  129. /// Decodes the provided data into a Private RSA Key
  130. ///
  131. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.2)
  132. /// ```
  133. /// ==========================
  134. /// RSA PrivateKey Structure
  135. /// ==========================
  136. ///
  137. /// RSAPrivateKey ::= SEQUENCE {
  138. /// version Version,
  139. /// modulus INTEGER, -- n
  140. /// publicExponent INTEGER, -- e
  141. /// privateExponent INTEGER, -- d
  142. /// prime1 INTEGER, -- p
  143. /// prime2 INTEGER, -- q
  144. /// exponent1 INTEGER, -- d mod (p-1)
  145. /// exponent2 INTEGER, -- d mod (q-1)
  146. /// coefficient INTEGER, -- (inverse of q) mod p
  147. /// otherPrimeInfos OtherPrimeInfos OPTIONAL
  148. /// }
  149. /// ```
  150. internal convenience init(privateDER der: Array<UInt8>) throws {
  151. let asn = try ASN1.Decoder.decode(data: Data(der))
  152. // Enforce the above ASN Structure (do we need to extract and verify the eponents and coefficients?)
  153. guard case .sequence(let params) = asn else { throw Error.invalidDERFormat }
  154. guard params.count >= 9 else { throw Error.invalidDERFormat }
  155. guard case .integer(let version) = params[0] else { throw Error.invalidDERFormat }
  156. guard case .integer(let modulus) = params[1] else { throw Error.invalidDERFormat }
  157. guard case .integer(let publicExponent) = params[2] else { throw Error.invalidDERFormat }
  158. guard case .integer(let privateExponent) = params[3] else { throw Error.invalidDERFormat }
  159. guard case .integer(let prime1) = params[4] else { throw Error.invalidDERFormat }
  160. guard case .integer(let prime2) = params[5] else { throw Error.invalidDERFormat }
  161. guard case .integer(let exponent1) = params[6] else { throw Error.invalidDERFormat }
  162. guard case .integer(let exponent2) = params[7] else { throw Error.invalidDERFormat }
  163. guard case .integer(let coefficient) = params[8] else { throw Error.invalidDERFormat }
  164. // Are there other versions out there? Is this even the version?
  165. guard version == Data(hex: "0x00") else { throw Error.invalidDERFormat }
  166. // Ensure the supplied parameters are correct...
  167. // Calculate modulus
  168. guard BigUInteger(modulus) == BigUInteger(prime1) * BigUInteger(prime2) else { throw Error.invalidPrimes }
  169. // Calculate public and private exponent
  170. let phi = (BigUInteger(prime1) - 1) * (BigUInteger(prime2) - 1)
  171. guard let d = BigUInteger(publicExponent).inverse(phi) else { throw Error.invalidPrimes }
  172. guard BigUInteger(privateExponent) == d else { throw Error.invalidPrimes }
  173. // Ensure the provided coefficient is correct (derived from the primes)
  174. // - Note: this might be overkill, cause we don't store the coefficient, but the extra check probably isn't the worse thing
  175. guard let calculatedCoefficient = BigUInteger(prime2).inverse(BigUInteger(prime1)) else { throw RSA.Error.unableToCalculateCoefficient }
  176. guard calculatedCoefficient == BigUInteger(coefficient) else { throw RSA.Error.invalidPrimes }
  177. // Ensure the provided exponents are correct as well
  178. // - Note: this might be overkill, cause we don't store them, but the extra check probably isn't the worse thing
  179. guard (d % (BigUInteger(prime1) - 1)) == BigUInteger(exponent1) else { throw RSA.Error.invalidPrimes }
  180. guard (d % (BigUInteger(prime2) - 1)) == BigUInteger(exponent2) else { throw RSA.Error.invalidPrimes }
  181. // Proceed with regular initialization
  182. self.init(n: BigUInteger(modulus), e: BigUInteger(publicExponent), d: BigUInteger(privateExponent), p: BigUInteger(prime1), q: BigUInteger(prime2))
  183. }
  184. }
  185. // MARK: CS.BigUInt extension
  186. extension BigUInteger {
  187. public static func generatePrime(_ width: Int) -> BigUInteger {
  188. // Note: Need to find a better way to generate prime numbers
  189. while true {
  190. var random = BigUInteger.randomInteger(withExactWidth: width)
  191. random |= BigUInteger(1)
  192. if random.isPrime() {
  193. return random
  194. }
  195. }
  196. }
  197. }
  198. // MARK: DER Exports (See #892)
  199. extension RSA {
  200. /// The DER representation of this public key
  201. ///
  202. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.1)
  203. /// ```
  204. /// =========================
  205. /// RSA PublicKey Structure
  206. /// =========================
  207. ///
  208. /// RSAPublicKey ::= SEQUENCE {
  209. /// modulus INTEGER, -- n
  210. /// publicExponent INTEGER -- e
  211. /// }
  212. /// ```
  213. func publicKeyDER() throws -> Array<UInt8> {
  214. let mod = self.n.serialize()
  215. let pubKeyAsnNode: ASN1.Node =
  216. .sequence(nodes: [
  217. .integer(data: DER.i2ospData(x: mod.bytes, size: self.keySize / 8)),
  218. .integer(data: DER.i2ospData(x: self.e.serialize().bytes, size: 3))
  219. ])
  220. return ASN1.Encoder.encode(pubKeyAsnNode)
  221. }
  222. /// The DER representation of this private key
  223. ///
  224. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.2)
  225. /// ```
  226. /// ==========================
  227. /// RSA PrivateKey Structure
  228. /// ==========================
  229. ///
  230. /// RSAPrivateKey ::= SEQUENCE {
  231. /// version Version,
  232. /// modulus INTEGER, -- n
  233. /// publicExponent INTEGER, -- e
  234. /// privateExponent INTEGER, -- d
  235. /// prime1 INTEGER, -- p
  236. /// prime2 INTEGER, -- q
  237. /// exponent1 INTEGER, -- d mod (p-1)
  238. /// exponent2 INTEGER, -- d mod (q-1)
  239. /// coefficient INTEGER, -- (inverse of q) mod p
  240. /// otherPrimeInfos OtherPrimeInfos OPTIONAL
  241. /// }
  242. /// ```
  243. func privateKeyDER() throws -> Array<UInt8> {
  244. // Make sure we have a private key
  245. guard let d = d else { throw RSA.Error.noPrivateKey }
  246. // Make sure we have access to our primes
  247. guard let primes = primes else { throw RSA.Error.noPrimes }
  248. // Make sure we can calculate our coefficient (inverse of q mod p)
  249. guard let coefficient = primes.q.inverse(primes.p) else { throw RSA.Error.unableToCalculateCoefficient }
  250. let bitWidth = self.keySize / 8
  251. let paramWidth = bitWidth / 2
  252. // Structure the data
  253. let mod = self.n.serialize()
  254. let privateKeyAsnNode: ASN1.Node =
  255. .sequence(nodes: [
  256. .integer(data: Data(hex: "0x00")),
  257. .integer(data: DER.i2ospData(x: mod.bytes, size: bitWidth)),
  258. .integer(data: DER.i2ospData(x: self.e.serialize().bytes, size: 3)),
  259. .integer(data: DER.i2ospData(x: d.serialize().bytes, size: bitWidth)),
  260. .integer(data: DER.i2ospData(x: primes.p.serialize().bytes, size: paramWidth)),
  261. .integer(data: DER.i2ospData(x: primes.q.serialize().bytes, size: paramWidth)),
  262. .integer(data: DER.i2ospData(x: (d % (primes.p - 1)).serialize().bytes, size: paramWidth)),
  263. .integer(data: DER.i2ospData(x: (d % (primes.q - 1)).serialize().bytes, size: paramWidth)),
  264. .integer(data: DER.i2ospData(x: coefficient.serialize().bytes, size: paramWidth))
  265. ])
  266. // Encode and return the data
  267. return ASN1.Encoder.encode(privateKeyAsnNode)
  268. }
  269. /// This method returns the DER encoding of the RSA Key.
  270. ///
  271. /// - Returns: The ASN1 DER Encoding of the Public or Private RSA Key
  272. /// - Note: If the RSA Key is a private key, the private key representation is returned
  273. /// - Note: If the RSA Key is a public key, the public key representation is returned
  274. /// - Note: If you'd like to only export the public DER of an RSA Key call the `publicKeyExternalRepresentation()` method
  275. /// - Note: This method returns the same data as Apple's `SecKeyCopyExternalRepresentation` method.
  276. ///
  277. /// An example of converting a CryptoSwift RSA key to a SecKey RSA key
  278. /// ```
  279. /// /// Starting with a CryptoSwift RSA Key
  280. /// let rsaKey = try RSA(keySize: 1024)
  281. ///
  282. /// /// Define your Keys attributes
  283. /// let attributes: [String:Any] = [
  284. /// kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
  285. /// kSecAttrKeyClass as String: kSecAttrKeyClassPrivate, // or kSecAttrKeyClassPublic
  286. /// kSecAttrKeySizeInBits as String: 1024, // The appropriate bits
  287. /// kSecAttrIsPermanent as String: false
  288. /// ]
  289. /// var error:Unmanaged<CFError>? = nil
  290. /// guard let rsaSecKey = try SecKeyCreateWithData(rsaKey.externalRepresentation() as CFData, attributes as CFDictionary, &error) else {
  291. /// /// Error constructing SecKey from raw key data
  292. /// return
  293. /// }
  294. ///
  295. /// /// You now have an RSA SecKey for use with Apple's Security framework
  296. /// ```
  297. ///
  298. /// An example of converting a SecKey RSA key to a CryptoSwift RSA key
  299. /// ```
  300. /// /// Starting with a SecKey RSA Key
  301. /// let rsaSecKey:SecKey
  302. ///
  303. /// /// Copy External Representation
  304. /// var externalRepError:Unmanaged<CFError>?
  305. /// guard let cfdata = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) else {
  306. /// /// Failed to copy external representation for RSA SecKey
  307. /// return
  308. /// }
  309. ///
  310. /// /// Instantiate the RSA Key from the raw external representation
  311. /// let rsaKey = try RSA(rawRepresentation: cfdata as Data)
  312. ///
  313. /// /// You now have a CryptoSwift RSA Key
  314. /// ```
  315. ///
  316. func externalRepresentation() throws -> Data {
  317. if self.primes != nil {
  318. return try Data(self.privateKeyDER())
  319. } else {
  320. return try Data(self.publicKeyDER())
  321. }
  322. }
  323. }
  324. // MARK: CustomStringConvertible Conformance
  325. extension RSA: CustomStringConvertible {
  326. public var description: String {
  327. if self.d != nil {
  328. return "CryptoSwift.RSA.PrivateKey<\(self.keySize)>"
  329. } else {
  330. return "CryptoSwift.RSA.PublicKey<\(self.keySize)>"
  331. }
  332. }
  333. }