RSA.swift 15 KB

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