- Notifications
You must be signed in to change notification settings - Fork352
RSA public/private key encryption in Swift
License
TakeScoop/SwiftyRSA
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Maintainer(s):@ikeith
Public key RSA encryption in Swift.
SwiftyRSA is used in theScoopiOS 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{letpublicKey=tryPublicKey(pemNamed:"public")letstr="Clear String"letclear=tryClearMessage(string: str, using:.utf8)letencrypted=try clear.encrypted(with: publicKey, padding:.PKCS1)letdata= encencrypted.dataprint(data)letbase64String= encrypted.base64Stringprint(base64String)}catch{print(error)}
letprivateKey=tryPrivateKey(pemNamed:"private")letencrypted=tryEncryptedMessage(base64Encoded:"AAA===")letclear=try encrypted.decrypted(with: privateKey, padding:.PKCS1)// Then you can use:letdata= clear.dataletbase64String= clear.base64Stringletstring= clear.string(using:.utf8)
letpublicKey=tryPublicKey(derNamed:"public")letprivateKey=tryPrivateKey(derNamed:"private")
letpublicKey=tryPublicKey(pemNamed:"public")letprivateKey=tryPrivateKey(pemNamed:"private")
letpublicKey=tryPublicKey(pemEncoded: str)letprivateKey=tryPrivateKey(pemEncoded: str)
letpublicKey=tryPublicKey(base64Encoded: base64String)letprivateKey=tryPrivateKey(base64Encoded: base64String)
letpublicKey=tryPublicKey(data: data)letprivateKey=tryPrivateKey(data: data)
letpublicKey=tryPublicKey(reference: secKey)letprivateKey=tryPrivateKey(reference: secKey)
letstr="Clear Text"letclear=tryClearMessage(string: str, using:.utf8)letencrypted=try clear.encrypted(with: publicKey, padding:.PKCS1)letdata= encrypted.dataletbase64String= encrypted.base64Encoded
letencrypted=tryEncryptedMessage(base64Encoded: base64String)letclear=try encrypted.decrypted(with: privateKey, padding:.PKCS1)letdata= clear.dataletbase64String= clear.base64Encodedletstring=try clear.string(using:.utf8)
SwiftyRSA can sign data with a private key. SwiftyRSA will calculate a SHA digest of the suppliedString
/Data
and use this to generate the digital signature.
letclear=tryClearMessage(string:"Clear Text", using:.utf8)letsignature= clear.signed(with: privateKey, digestType:.sha1)letdata= signature.dataletbase64String= signature.base64String
SwiftyRSA can verify digital signatures with a public key. SwiftyRSA will calculate a digest of the suppliedString
/Data
and use this to verify the digital signature.
letsignature=trySignature(base64Encoded:"AAA===")letisSuccessful=try clear.verify(with: publicKey, signature: signature, digestType:.sha1)
letkeyPair=SwiftyRSA.generateRSAKeyPair(sizeInBits:2048)letprivateKey= keyPair.privateKeyletpublicKey= keyPair.publicKey
letpem=try key.pemString()letbase64=try key.base64String()letdata=try key.data()letreference= key.referenceletoriginalData= 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.
letpublicKey=PublicKey(data: data)letpublicKeyData=try publicKey.data()letpublicKey_with_X509_header=trySwiftyRSA.prependX509KeyHeader(keyData: publicKeyData)
letpublicKey_headerLess:Data=trySwiftyRSA.stripKeyHeader(keyData: publicKey_with_X509_header)
Warning : Storing (with SwiftyRSA's methods) or creating aPublicKey
instance will automatically strip the header from the key. For more info, seeUnder the hood above.
Usessh-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
- http://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
About
RSA public/private key encryption in Swift