Maintainer(s): @ikeith
Public key RSA encryption in Swift.
SwiftyRSA is used in the Scoop iOS app to encrypt driver license numbers before submitting them to Checkr through our API.
SwiftyRSA uses Swift 5.0 and requires Xcode 10.2+.
With Cocoapods:
pod 'SwiftyRSA'
With Carthage:
github "TakeScoop/SwiftyRSA"
pod 'SwiftyRSA/ObjC'
do {
let publicKey = try PublicKey(pemNamed: "public")
let str = "Clear String"
let clear = try ClearMessage(string: str, using: .utf8)
let encrypted = try clear.encrypted(with: publicKey, padding: .PKCS1)
let data = encencrypted.data
print(data)
let base64String = encrypted.base64String
print(base64String)
} catch {
print(error)
}
let privateKey = try PrivateKey(pemNamed: "private")
let encrypted = try EncryptedMessage(base64Encoded: "AAA===")
let clear = try encrypted.decrypted(with: privateKey, padding: .PKCS1)
// Then you can use:
let data = clear.data
let base64String = clear.base64String
let string = clear.string(using: .utf8)
let publicKey = try PublicKey(derNamed: "public")
let privateKey = try PrivateKey(derNamed: "private")
let publicKey = try PublicKey(pemNamed: "public")
let privateKey = try PrivateKey(pemNamed: "private")
let publicKey = try PublicKey(pemEncoded: str)
let privateKey = try PrivateKey(pemEncoded: str)
let publicKey = try PublicKey(base64Encoded: base64String)
let privateKey = try PrivateKey(base64Encoded: base64String)
let publicKey = try PublicKey(data: data)
let privateKey = try PrivateKey(data: data)
let publicKey = try PublicKey(reference: secKey)
let privateKey = try PrivateKey(reference: secKey)
let str = "Clear Text"
let clear = try ClearMessage(string: str, using: .utf8)
let encrypted = try clear.encrypted(with: publicKey, padding: .PKCS1)
let data = encrypted.data
let base64String = encrypted.base64Encoded
let encrypted = try EncryptedMessage(base64Encoded: base64String)
let clear = try encrypted.decrypted(with: privateKey, padding: .PKCS1)
let data = clear.data
let base64String = clear.base64Encoded
let string = try clear.string(using: .utf8)
SwiftyRSA can sign data with a private key. SwiftyRSA will calculate a SHA digest of the supplied String
/Data
and use this to generate the digital signature.
let clear = try ClearMessage(string: "Clear Text", using: .utf8)
let signature = clear.signed(with: privateKey, digestType: .sha1)
let data = signature.data
let base64String = signature.base64String
SwiftyRSA can verify digital signatures with a public key. SwiftyRSA will calculate a digest of the supplied String
/Data
and use this to verify the digital signature.
let signature = try Signature(base64Encoded: "AAA===")
let isSuccessful = try clear.verify(with: publicKey, signature: signature, digestType: .sha1)
let keyPair = SwiftyRSA.generateRSAKeyPair(sizeInBits: 2048)
let privateKey = keyPair.privateKey
let publicKey = keyPair.publicKey
let pem = try key.pemString()
let base64 = try key.base64String()
let data = try key.data()
let reference = key.reference
let originalData = key.originalData
SwiftyRSA supports X.509 certificate for public keys. SwiftyRSA can add the X.509 header to a headerless public key, or on the contrary strip it to get a key without a header.
let publicKey = PublicKey(data: data)
let publicKeyData = try publicKey.data()
let publicKey_with_X509_header = try SwiftyRSA.prependX509KeyHeader(keyData: publicKeyData)
let publicKey_headerLess: Data = try SwiftyRSA.stripKeyHeader(keyData: publicKey_with_X509_header)
Warning : Storing (with SwiftyRSA's methods) or creating a PublicKey
instance will automatically strip the header from the key. For more info, see Under the hood above.
Use ssh-keygen
to generate a PEM public key and a PEM private key. SwiftyRSA also supports DER public keys.
$ ssh-keygen -t rsa -m PEM -f ~/mykey -N ''
$ cat ~/mykey > ~/private.pem
$ ssh-keygen -f ~/mykey.pub -e -m pem > ~/public.pem
Your keys are now in ~/public.pem
and ~/private.pem
. Don't forget to move ~/mykey
and ~/mykey.pub
to a secure place.
To enable using public/private RSA keys on iOS, SwiftyRSA uses a couple techniques like X.509 header stripping so that the keychain accepts them.
Click here for more details
When encrypting using a public key:
- If the key is in PEM format, get rid of its meta data and convert it to Data
- Strip the public key X.509 header, otherwise the keychain won't accept it
- Add the public key to the keychain, with a random tag
- Get a reference on the key using the key tag
- Use
SecKeyEncrypt
to encrypt aClearMessage
using the key reference and the message data. - Store the resulting encrypted data to an
EncryptedMessage
- When the key gets deallocated, delete the public key from the keychain using its tag
When decrypting using a private key:
- Get rid of PEM meta data and convert to Data
- Add the private key to the app keychain, with a random tag
- Get a reference on the key using the key tag
- Use
SecKeyDecrypt
to decrypt anEncryptedMessage
using the key reference and the encrypted message data - Store the resulting decrypted data to a
ClearMessage
- Delete private key from keychain using tag
- https://blog.flirble.org/2011/01/05/rsa-public-key-openssl-ios/
- https://github.com/lancy/RSADemo
- https://github.com/btnguyen2k/swift-rsautils
This project is copyrighted under the MIT license. Complete license can be found here: https://github.com/TakeScoop/SwiftyRSA/blob/master/LICENSE