1. Use OpenSSL in terminal to generate a RSA private and public key pair in PEM format:
Generate a 1024-bit private key:
openssl genrsa -out private_key.pem 1024
Obtain a public key from the private key:
openssl rsa -in private_key.pem -pubout -out public_key.pem
Convert the private key to PKCS#8 format:
openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -out private_key_pkcs8.pem -nocrypt
This format conversion is required because RSAUtils.swift works with PKCS#8 format, but not the traditional PKCS#1 format.
Header and footer of the traditional PKCS#1 format:
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
Header and footer of the PKCS#8 format:
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
2. Download Swift-RSAUtils. Find out the RSAUtils.swift file in the downloaded folder.
3. Create a new Single View Application project in Xcode.
4. Add RSAUtils.swift and the two private/public PEM files ( private_key_pkcs8.pem and public_key.pem ) to the project.
5. Modify ViewController.swift as below:
import UIKit
class ViewController: UIViewController {
// tag name to access the stored private key stored in keychain
let TAG_PRIVATE_KEY = "com.mycompany.tag_private"
// tag name to access the stored public key in keychain
let TAG_PUBLIC_KEY = "com.mycompany.tag_public"
override func viewDidLoad() {
super.viewDidLoad()
let PUBLIC_KEY = getKeyStringFromPEM("public_key")
let PRIVATE_KEY = getKeyStringFromPEM("private_key_pkcs8")
let message = "This is my message."
let data = (message as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
let encryptedData = RSAUtils.encryptWithRSAPublicKey(data, pubkeyBase64: PUBLIC_KEY, keychainTag: TAG_PUBLIC_KEY)!
if let decryptedData = RSAUtils.decryptWithRSAPrivateKey(encryptedData, privkeyBase64: PRIVATE_KEY, keychainTag: TAG_PRIVATE_KEY) {
let decryptedString = NSString(data: decryptedData, encoding: NSUTF8StringEncoding)!
print(decryptedString)
} else {
print("Unable to decrypt.")
}
}
func getKeyStringFromPEM(name: String) -> String {
let bundle = NSBundle.mainBundle()
let keyPath = bundle.pathForResource(name, ofType: "pem")!
let keyString = try! NSString(contentsOfFile: keyPath, encoding: NSUTF8StringEncoding)
let keyArray = keyString.componentsSeparatedByString("\n") //Remove new line characters
var keyOutput : String = ""
for item in keyArray {
if !item.containsString("-----") { //Example: -----BEGIN PUBLIC KEY-----
keyOutput += item //Join elements of the text array together as a single string
}
}
return keyOutput
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
References:
Encrypt/decrypt a string with RSA public/private PEM files using Python
what is the differences between “BEGIN RSA PRIVATE KEY” and “BEGIN PRIVATE KEY”
Swift how to import rsa key
Encrypt/decrypt a string with code-generated RSA public/private keys in Swift
OpenSSL RSA commands to encrypt/decrypt a message in terminal (Mac)
Go back to Communication between iOS device (Client) and Raspberry Pi (Server)
Thank you for the tutorial Enoch!
ReplyDeleteI'm guessing if the let message = " " is changed to let message = myTextField.tex, then you can encrypt the text from text field? And also, if print(decryptedString) is changed to outputTextLabel.text = decryptedString, the decrypted text will be displayed?
I'm sorry for the dumb questions, but I'm not advanced with swift.
And thanks again for the tutorial Enoch!
I forgot one more thing. When you convert the code to Swift 3 the last line: if !item.containsString("-----") { //Example: -----BEGIN PUBLIC KEY-----
ReplyDeletegives me an error. How should I change it so I don't get error?
thank you . very much ..for this very useful article
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteWhy the below code is require?
ReplyDelete// tag name to access the stored private key stored in keychain
let TAG_PRIVATE_KEY = "com.mycompany.tag_private"
// tag name to access the stored public key in keychain
let TAG_PUBLIC_KEY = "com.mycompany.tag_public"
I tried put some random string as TAG_PUBLIC_KEY and it gave me the same encrypted string.
Here is my repo https://github.com/anirudhamahale/RSA-Encryption
and how do I tag the pem file in keychain Access?
Is there any option to use only public key for encryption and decryption?
ReplyDelete