RSASecKeyTests.swift 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. //
  2. // RSASecKeyTests.swift
  3. //
  4. //
  5. // Created by Brandon Toms on 7/6/22.
  6. //
  7. #if canImport(Security)
  8. import Security
  9. import XCTest
  10. @testable import CryptoSwift
  11. final class RSASecKeyTests: XCTestCase {
  12. // MARK: SecKey <-> RSA Interoperability
  13. // From CryptoSwift RSA -> External Representation -> SecKey
  14. func testRSAExternalRepresentationPrivate() throws {
  15. // Generate a CryptoSwift RSA Key
  16. let rsaCryptoSwift = try RSA(keySize: 1024)
  17. // Get the key's rawExternalRepresentation
  18. let rsaCryptoSwiftRawRep = try rsaCryptoSwift.privateKeyDER()
  19. // We should be able to instantiate an RSA SecKey from this data
  20. let attributes: [String: Any] = [
  21. kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
  22. kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
  23. kSecAttrKeySizeInBits as String: 1024,
  24. kSecAttrIsPermanent as String: false
  25. ]
  26. var error: Unmanaged<CFError>?
  27. guard let rsaSecKey = SecKeyCreateWithData(Data(rsaCryptoSwiftRawRep) as CFData, attributes as CFDictionary, &error) else {
  28. XCTFail("Error constructing SecKey from raw key data: \(error.debugDescription)")
  29. return
  30. }
  31. // Get the SecKey's external representation
  32. var externalRepError: Unmanaged<CFError>?
  33. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  34. XCTFail("Failed to copy external representation for RSA SecKey")
  35. return
  36. }
  37. // Ensure both the CryptoSwift Ext Rep and the SecKey Ext Rep match
  38. XCTAssertEqual(rsaSecKeyRawRep, Data(rsaCryptoSwiftRawRep))
  39. XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
  40. }
  41. /// From CryptoSwift RSA -> External Representation -> SecKey
  42. func testRSAExternalRepresentationPublic() throws {
  43. // Generate a CryptoSwift RSA Key
  44. let rsaCryptoSwift = try RSA(keySize: 1024)
  45. // Get the key's rawExternalRepresentation
  46. let rsaCryptoSwiftRawRep = try rsaCryptoSwift.publicKeyDER()
  47. // We should be able to instantiate an RSA SecKey from this data
  48. let attributes: [String: Any] = [
  49. kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
  50. kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
  51. kSecAttrKeySizeInBits as String: 1024,
  52. kSecAttrIsPermanent as String: false
  53. ]
  54. var error: Unmanaged<CFError>?
  55. guard let rsaSecKey = SecKeyCreateWithData(Data(rsaCryptoSwiftRawRep) as CFData, attributes as CFDictionary, &error) else {
  56. XCTFail("Error constructing SecKey from raw key data: \(error.debugDescription)")
  57. return
  58. }
  59. // Get the SecKey's external representation
  60. var externalRepError: Unmanaged<CFError>?
  61. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  62. XCTFail("Failed to copy external representation for RSA SecKey")
  63. return
  64. }
  65. // Ensure both the CryptoSwift Ext Rep and the SecKey Ext Rep match
  66. XCTAssertEqual(rsaSecKeyRawRep, Data(rsaCryptoSwiftRawRep))
  67. XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.publicKeyExternalRepresentation())
  68. }
  69. /// From SecKey -> External Representation -> CryptoSwift RSA
  70. func testSecKeyExternalRepresentationPrivate() throws {
  71. // Generate a SecKey RSA Key
  72. let parameters: [CFString: Any] = [
  73. kSecAttrKeyType: kSecAttrKeyTypeRSA,
  74. kSecAttrKeySizeInBits: 1024
  75. ]
  76. var error: Unmanaged<CFError>?
  77. // Generate the RSA SecKey
  78. guard let rsaSecKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error) else {
  79. XCTFail("Key Generation Error: \(error.debugDescription)")
  80. return
  81. }
  82. // Lets grab the external representation
  83. var externalRepError: Unmanaged<CFError>?
  84. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  85. XCTFail("Failed to copy external representation for RSA SecKey")
  86. return
  87. }
  88. // Ensure we can import the private RSA key into CryptoSwift
  89. let rsaCryptoSwift = try RSA(rawRepresentation: rsaSecKeyRawRep)
  90. XCTAssertNotNil(rsaCryptoSwift.d)
  91. XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
  92. }
  93. /// From SecKey -> External Representation -> CryptoSwift RSA
  94. func testSecKeyExternalRepresentationPublic() throws {
  95. // Generate a SecKey RSA Key
  96. let parameters: [CFString: Any] = [
  97. kSecAttrKeyType: kSecAttrKeyTypeRSA,
  98. kSecAttrKeySizeInBits: 1024
  99. ]
  100. var error: Unmanaged<CFError>?
  101. // Generate the RSA SecKey
  102. guard let rsaSecKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error) else {
  103. XCTFail("Key Generation Error: \(error.debugDescription)")
  104. return
  105. }
  106. // Extract the public key from the private RSA SecKey
  107. guard let rsaSecKeyPublic = SecKeyCopyPublicKey(rsaSecKey) else {
  108. XCTFail("Public Key Extraction Error")
  109. return
  110. }
  111. // Lets grab the external representation of the public key
  112. var externalRepError: Unmanaged<CFError>?
  113. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKeyPublic, &externalRepError) as? Data else {
  114. XCTFail("Failed to copy external representation for RSA SecKey")
  115. return
  116. }
  117. // Ensure we can import the private RSA key into CryptoSwift
  118. let rsaCryptoSwift = try RSA(rawRepresentation: rsaSecKeyRawRep)
  119. XCTAssertNil(rsaCryptoSwift.d)
  120. XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
  121. }
  122. func testRSASecKey() throws {
  123. let tests = 1
  124. let messageToSign: String = "RSA Keys!"
  125. for _ in 0..<tests {
  126. // Generate a SecKey RSA Key
  127. let parameters: [CFString: Any] = [
  128. kSecAttrKeyType: kSecAttrKeyTypeRSA,
  129. kSecAttrKeySizeInBits: 1024
  130. ]
  131. var error: Unmanaged<CFError>?
  132. // Generate the RSA SecKey
  133. guard let rsaSecKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error) else {
  134. XCTFail("Key Generation Error: \(error.debugDescription)")
  135. break
  136. }
  137. // Lets grab the external representation
  138. var externalRepError: Unmanaged<CFError>?
  139. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  140. XCTFail("Failed to copy external representation for RSA SecKey")
  141. break
  142. }
  143. // Ensure we can import the private RSA key into CryptoSwift
  144. let rsaCryptoSwift = try RSA(rawRepresentation: rsaSecKeyRawRep)
  145. // Sign the message with both keys and ensure their the same
  146. let csSignature = try rsaCryptoSwift.sign(messageToSign.bytes, variant: .message_pkcs1v15_SHA256)
  147. let skSignature = try secKeySign(messageToSign.bytes, variant: .rsaSignatureMessagePKCS1v15SHA256, withKey: rsaSecKey)
  148. XCTAssertEqual(csSignature, skSignature.bytes, "Signature don't match!")
  149. XCTAssertTrue(try rsaCryptoSwift.verify(signature: skSignature.bytes, for: messageToSign.bytes, variant: .message_pkcs1v15_SHA256))
  150. XCTAssertTrue(try self.secKeyVerify(csSignature, forBytes: messageToSign.bytes, usingVariant: .rsaSignatureMessagePKCS1v15SHA256, withKey: rsaSecKey))
  151. // Encrypt with SecKey
  152. let skEncryption = try secKeyEncrypt(messageToSign.bytes, usingVariant: .rsaEncryptionRaw, withKey: rsaSecKey)
  153. // Decrypt with CryptoSwift Key
  154. XCTAssertEqual(try rsaCryptoSwift.decrypt(skEncryption.bytes, variant: .unsafe), messageToSign.bytes, "CryptoSwift Decryption of SecKey Encryption Failed")
  155. // Encrypt with CryptoSwift
  156. let csEncryption = try rsaCryptoSwift.encrypt(messageToSign.bytes, variant: .unsafe)
  157. // Decrypt with SecKey
  158. XCTAssertEqual(try self.secKeyDecrypt(csEncryption, usingVariant: .rsaEncryptionRaw, withKey: rsaSecKey).bytes, messageToSign.bytes, "SecKey Decryption of CryptoSwift Encryption Failed")
  159. //print(csEncryption)
  160. //print(skEncryption.bytes)
  161. XCTAssertEqual(csEncryption, skEncryption.bytes, "Encrypted Data Does Not Match")
  162. // Encrypt with SecKey
  163. let skEncryption2 = try secKeyEncrypt(messageToSign.bytes, usingVariant: .rsaEncryptionPKCS1, withKey: rsaSecKey)
  164. // Decrypt with CryptoSwift Key
  165. XCTAssertEqual(try rsaCryptoSwift.decrypt(skEncryption2.bytes, variant: .pksc1v15), messageToSign.bytes, "CryptoSwift Decryption of SecKey Encryption Failed")
  166. // Encrypt with CryptoSwift
  167. let csEncryption2 = try rsaCryptoSwift.encrypt(messageToSign.bytes, variant: .pksc1v15)
  168. // Decrypt with SecKey
  169. XCTAssertEqual(try self.secKeyDecrypt(csEncryption2, usingVariant: .rsaEncryptionPKCS1, withKey: rsaSecKey).bytes, messageToSign.bytes, "SecKey Decryption of CryptoSwift Encryption Failed")
  170. print(csEncryption2.count)
  171. print(skEncryption2.bytes.count)
  172. }
  173. }
  174. private func secKeySign(_ bytes: Array<UInt8>, variant: SecKeyAlgorithm, withKey key: SecKey) throws -> Data {
  175. var error: Unmanaged<CFError>?
  176. // Sign the data
  177. guard let signature = SecKeyCreateSignature(
  178. key,
  179. variant,
  180. Data(bytes) as CFData,
  181. &error
  182. ) as Data?
  183. else { throw NSError(domain: "Failed to sign bytes: \(bytes)", code: 0) }
  184. return signature
  185. }
  186. private func secKeyVerify(_ signature: Array<UInt8>, forBytes bytes: Array<UInt8>, usingVariant variant: SecKeyAlgorithm, withKey key: SecKey) throws -> Bool {
  187. let pubKey = SecKeyCopyPublicKey(key)!
  188. var error: Unmanaged<CFError>?
  189. // Perform the signature verification
  190. let result = SecKeyVerifySignature(
  191. pubKey,
  192. variant,
  193. Data(bytes) as CFData,
  194. Data(signature) as CFData,
  195. &error
  196. )
  197. // Throw the error if we encountered one...
  198. if let error = error { throw error.takeRetainedValue() as Error }
  199. // return the result of the verification
  200. return result
  201. }
  202. private func secKeyEncrypt(_ bytes: Array<UInt8>, usingVariant variant: SecKeyAlgorithm, withKey key: SecKey) throws -> Data {
  203. let pubKey = SecKeyCopyPublicKey(key)!
  204. var error: Unmanaged<CFError>?
  205. guard let encryptedData = SecKeyCreateEncryptedData(pubKey, variant, Data(bytes) as CFData, &error) else {
  206. throw NSError(domain: "Error Encrypting Data: \(error.debugDescription)", code: 0, userInfo: nil)
  207. }
  208. // Throw the error if we encountered one...
  209. if let error = error { throw error.takeRetainedValue() as Error }
  210. // return the result of the encryption
  211. return encryptedData as Data
  212. }
  213. private func secKeyDecrypt(_ bytes: Array<UInt8>, usingVariant variant: SecKeyAlgorithm, withKey key: SecKey) throws -> Data {
  214. var error: Unmanaged<CFError>?
  215. guard let decryptedData = SecKeyCreateDecryptedData(key, variant, Data(bytes) as CFData, &error) else {
  216. throw NSError(domain: "Error Decrypting Data: \(error.debugDescription)", code: 0, userInfo: nil)
  217. }
  218. return (decryptedData as Data).drop { $0 == 0x00 }
  219. }
  220. func testCreateTestFixture() throws {
  221. let keySize = 1056
  222. let messages = [
  223. "",
  224. "👋",
  225. "RSA Keys",
  226. "CryptoSwift RSA Keys!",
  227. "CryptoSwift RSA Keys are really cool! They support encrypting / decrypting messages, signing and verifying signed messages, and importing and exporting encrypted keys for use between sessions 🔐"
  228. ]
  229. print(messages.map { $0.bytes.count })
  230. /// Generate a SecKey RSA Key
  231. let parameters: [CFString: Any] = [
  232. kSecAttrKeyType: kSecAttrKeyTypeRSA,
  233. kSecAttrKeySizeInBits: keySize
  234. ]
  235. var error: Unmanaged<CFError>?
  236. // Generate the RSA SecKey
  237. guard let rsaSecKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error) else {
  238. XCTFail("Key Generation Error: \(error.debugDescription)")
  239. return
  240. }
  241. // Extract the public key from the private RSA SecKey
  242. guard let rsaSecKeyPublic = SecKeyCopyPublicKey(rsaSecKey) else {
  243. XCTFail("Public Key Extraction Error")
  244. return
  245. }
  246. /// Lets grab the external representation of the public key
  247. var publicExternalRepError: Unmanaged<CFError>?
  248. guard let publicRSASecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKeyPublic, &publicExternalRepError) as? Data else {
  249. XCTFail("Failed to copy external representation for RSA SecKey")
  250. return
  251. }
  252. /// Lets grab the external representation of the public key
  253. var privateExternalRepError: Unmanaged<CFError>?
  254. guard let privateRSASecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &privateExternalRepError) as? Data else {
  255. XCTFail("Failed to copy external representation for RSA SecKey")
  256. return
  257. }
  258. var template = FixtureTemplate2
  259. template = template.replacingOccurrences(of: "{{KEY_SIZE}}", with: "\(keySize)")
  260. template = template.replacingOccurrences(of: "{{PUBLIC_DER}}", with: "\(publicRSASecKeyRawRep.base64EncodedString())")
  261. template = template.replacingOccurrences(of: "{{PRIVATE_DER}}", with: "\(privateRSASecKeyRawRep.base64EncodedString())")
  262. var messageEntries: [String] = []
  263. for message in messages {
  264. var messageTemplate = MessageTemplate
  265. messageTemplate = messageTemplate.replacingOccurrences(of: "{{PLAINTEXT_MESSAGE}}", with: message)
  266. let encryptedMessages = try encrypt(data: message.data(using: .utf8)!, with: rsaSecKeyPublic)
  267. messageTemplate = messageTemplate.replacingOccurrences(of: "{{ENCRYPTED_MESSAGES}}", with: encryptedMessages.joined(separator: ",\n\t\t "))
  268. let signedMessages = try sign(message: message.data(using: .utf8)!, using: rsaSecKey)
  269. messageTemplate = messageTemplate.replacingOccurrences(of: "{{SIGNED_MESSAGES}}", with: signedMessages.joined(separator: ",\n\t\t "))
  270. messageEntries.append(messageTemplate)
  271. }
  272. template = template.replacingOccurrences(of: "{{MESSAGE_TEMPLATES}}", with: "\(messageEntries.joined(separator: ",\n\t"))")
  273. print(template)
  274. }
  275. }
  276. extension RSASecKeyTests {
  277. static func allTests() -> [(String, (RSASecKeyTests) -> () throws -> Void)] {
  278. let tests = [
  279. ("testRSAExternalRepresentationPrivate", testRSAExternalRepresentationPrivate),
  280. ("testRSAExternalRepresentationPublic", testRSAExternalRepresentationPublic),
  281. ("testSecKeyExternalRepresentationPrivate", testSecKeyExternalRepresentationPrivate),
  282. ("testSecKeyExternalRepresentationPublic", testSecKeyExternalRepresentationPublic)
  283. ]
  284. return tests
  285. }
  286. }
  287. private let FixtureTemplate = """
  288. static let RSA_{{KEY_SIZE}} = Fixture(
  289. keySize: {{KEY_SIZE}},
  290. publicDER: \"\"\"
  291. {{PUBLIC_DER}}
  292. \"\"\",
  293. privateDER: \"\"\"
  294. {{PRIVATE_DER}}
  295. \"\"\",
  296. rawMessage: [
  297. {{PLAINTEXT_MESSAGE}}
  298. ],
  299. encryptedMessage: [
  300. {{ENCRYPTED_MESSAGES}}
  301. ],
  302. signedMessages: [
  303. {{SIGNED_MESSAGES}}
  304. ]
  305. )
  306. """
  307. private let FixtureTemplate2 = """
  308. static let RSA_{{KEY_SIZE}} = Fixture(
  309. keySize: {{KEY_SIZE}},
  310. publicDER: \"\"\"
  311. {{PUBLIC_DER}}
  312. \"\"\",
  313. privateDER: \"\"\"
  314. {{PRIVATE_DER}}
  315. \"\"\",
  316. messages: [
  317. {{MESSAGE_TEMPLATES}}
  318. ]
  319. )
  320. """
  321. private let MessageTemplate = """
  322. "{{PLAINTEXT_MESSAGE}}": (
  323. encryptedMessage: [
  324. {{ENCRYPTED_MESSAGES}}
  325. ],
  326. signedMessage: [
  327. {{SIGNED_MESSAGES}}
  328. ]
  329. )
  330. """
  331. //encryptedMessage: [
  332. // "algid:encrypt:RSA:raw": "{{ENCRYPTED_RAW}}",
  333. // "algid:encrypt:RSA:PKCS1": "{{ENCRYPTED_PKCS1}}"
  334. //],
  335. //signedMessages: [
  336. // "algid:sign:RSA:raw" : "{{SIGNATURE_RAW}}",
  337. // "algid:sign:RSA:digest-PKCS1v15" : "{{SIGNATURE_DIGEST_PKCS1v15}}",
  338. // "algid:sign:RSA:digest-PKCS1v15:SHA1" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA1}}",
  339. // "algid:sign:RSA:digest-PKCS1v15:SHA224" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA224}}",
  340. // "algid:sign:RSA:digest-PKCS1v15:SHA256" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA256}}",
  341. // "algid:sign:RSA:digest-PKCS1v15:SHA384" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA384}}",
  342. // "algid:sign:RSA:digest-PKCS1v15:SHA512" : "{{SIGNATURE_DIGEST_PKCS1v15_SHA512}}",
  343. // "algid:sign:RSA:message-PKCS1v15:SHA1" : "{{SIGNATURE_MESSAGE_PKCS1v15_SHA1}}",
  344. // "algid:sign:RSA:message-PKCS1v15:SHA224": "{{SIGNATURE_MESSAGE_PKCS1v15_SHA224}}",
  345. // "algid:sign:RSA:message-PKCS1v15:SHA256": "{{SIGNATURE_MESSAGE_PKCS1v15_SHA256}}",
  346. // "algid:sign:RSA:message-PKCS1v15:SHA384": "{{SIGNATURE_MESSAGE_PKCS1v15_SHA384}}",
  347. // "algid:sign:RSA:message-PKCS1v15:SHA512": "{{SIGNATURE_MESSAGE_PKCS1v15_SHA512}}"
  348. //]
  349. //private func printHexData16BytesWide(_ bytes:[UInt8]) {
  350. // print(bytes.toHexString().split(intoChunksOfLength: 32).map { $0.split(intoChunksOfLength: 2).map { "0x\($0.uppercased())" }.joined(separator: ", ") }.joined(separator: ",\n"))
  351. //}
  352. private func initSecKey(rawRepresentation unsafe: Data) throws -> SecKey {
  353. let attributes: [String: Any] = [
  354. kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
  355. kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
  356. kSecAttrKeySizeInBits as String: 1024,
  357. kSecAttrIsPermanent as String: false
  358. ]
  359. var error: Unmanaged<CFError>?
  360. guard let secKey = SecKeyCreateWithData(unsafe as CFData, attributes as CFDictionary, &error) else {
  361. throw NSError(domain: "Error constructing SecKey from raw key data: \(error.debugDescription)", code: 0, userInfo: nil)
  362. }
  363. return secKey
  364. }
  365. private func sign(message: Data, using key: SecKey) throws -> [String] {
  366. let algorithms: [SecKeyAlgorithm] = [
  367. .rsaSignatureRaw,
  368. //.rsaSignatureDigestPSSSHA1,
  369. //.rsaSignatureDigestPSSSHA224,
  370. //.rsaSignatureDigestPSSSHA256,
  371. //.rsaSignatureDigestPSSSHA384,
  372. //.rsaSignatureDigestPSSSHA512,
  373. .rsaSignatureDigestPKCS1v15Raw,
  374. .rsaSignatureDigestPKCS1v15SHA1,
  375. .rsaSignatureDigestPKCS1v15SHA224,
  376. .rsaSignatureDigestPKCS1v15SHA256,
  377. .rsaSignatureDigestPKCS1v15SHA384,
  378. .rsaSignatureDigestPKCS1v15SHA512,
  379. //.rsaSignatureMessagePSSSHA1,
  380. //.rsaSignatureMessagePSSSHA224,
  381. //.rsaSignatureMessagePSSSHA256,
  382. //.rsaSignatureMessagePSSSHA384,
  383. //.rsaSignatureMessagePSSSHA512,
  384. .rsaSignatureMessagePKCS1v15SHA1,
  385. .rsaSignatureMessagePKCS1v15SHA224,
  386. .rsaSignatureMessagePKCS1v15SHA256,
  387. .rsaSignatureMessagePKCS1v15SHA384,
  388. .rsaSignatureMessagePKCS1v15SHA512,
  389. ]
  390. var sigs: [String] = []
  391. for algo in algorithms {
  392. var error: Unmanaged<CFError>?
  393. // Sign the data
  394. guard let signature = SecKeyCreateSignature(
  395. key,
  396. algo,
  397. message as CFData,
  398. &error
  399. ) as Data?
  400. else {
  401. print("\"\(algo.rawValue)\": \"nil\",")
  402. sigs.append("\"\(algo.rawValue)\": \"\"")
  403. continue
  404. }
  405. // Throw the error if we encountered one
  406. if let error = error { print("\"\(algo.rawValue)\": \"\(error.takeRetainedValue())\","); continue }
  407. // Append the signature
  408. sigs.append("\"\(algo.rawValue)\": \"\(signature.base64EncodedString())\"")
  409. }
  410. return sigs
  411. }
  412. private func encrypt(data: Data, with key: SecKey) throws -> [String] {
  413. let algorithms: [SecKeyAlgorithm] = [
  414. .rsaEncryptionRaw,
  415. .rsaEncryptionPKCS1
  416. ]
  417. var encryptions: [String] = []
  418. for algo in algorithms {
  419. var error: Unmanaged<CFError>?
  420. guard let encryptedData = SecKeyCreateEncryptedData(key, algo, data as CFData, &error) as? Data else {
  421. print("\"\(algo.rawValue)\": \"\(error?.takeRetainedValue().localizedDescription ?? "nil")\",")
  422. encryptions.append("\"\(algo.rawValue)\": \"\"")
  423. continue
  424. }
  425. encryptions.append("\"\(algo.rawValue)\": \"\(encryptedData.base64EncodedString())\"")
  426. }
  427. return encryptions
  428. }
  429. #endif