RSA Encryption
swift rca encryption Estimated reading time: 8 minutesRecently, I encountered RSA encryption while working on a project and realized its critical role in securing data. RSA (Rivest-Shamir-Adleman) encryption is a public-key cryptographic system widely used for secure data transmission. Let’s explore its purpose, history, and functionality.
A Brief History of RSA
RSA was introduced in 1977 by Ron Rivest, Adi Shamir, and Leonard Adleman at MIT. It was the first algorithm for public-key cryptography that could encrypt and digitally sign data. Its foundation lies in number theory, specifically the difficulty of factoring large composite numbers, making it a reliable choice for securing communications.
How it Works
Below is a high-level overview of RSA’s process:
- Key Generation
- Select two large prime numbers ( p ) and ( q ).
- Compute ( n = p imes q ), where ( n ) is the modulus.
- Calculate ( \phi(n) = (p-1) imes (q-1) ).
- Choose a public exponent ( e ), and determine the private key ( d ), where ( d imes e \mod \phi(n) = 1 ).
- Encryption
- Plaintext ( M ) is converted to ciphertext ( C ) using the public key ( (e, n) ):
( C = M^e \mod n ).
- Plaintext ( M ) is converted to ciphertext ( C ) using the public key ( (e, n) ):
- Decryption
- The recipient uses their private key ( d ) to decrypt ( C ):
( M = C^d \mod n ).
- The recipient uses their private key ( d ) to decrypt ( C ):
This ASCII diagram provides a simplified, yet complete visualization of how RSA encryption works:
Public vs. Private Key
-
Public Key: Shared openly; used to encrypt data or verify digital signatures.
-
Private Key: Kept secret; used to decrypt data or create digital signatures.
This asymmetry ensures secure communication since only the holder of the private key can access encrypted messages or authenticate signatures.
Implementation
Here we have few moments - private key is something that we don’t want to share, so we need to store this key somewhere in safe place.
Luckely for us, Apple already think about this, and using Security
framework we can generate and store our key in keychain securely.
The process for rsa encryption will contains few steps:
- generate or obtain generated keys
- encrypt/decrypt value
Let’s review each step.
generate keys
As we want to manage both keys, we can simply wrap this idea into one model - RSAKeyModel
:
The most interesting part - it’s generating keys itself. For this purpose, let’s create a type, that will handle this - RSAProvider
.
To generate key, we must provide all preferences that we need. Keeping in mind, that we need a storage for keys for future reuse, we can do the following:
where:
kSecAttrIsPermanent
:true
: Indicates that the key will be stored persistently in the Keychain, so we can retrieve this key later and reuse.kSecAttrApplicationTag
:publicKeyTag
: Tags the public key with an identifier (publicKeyTag
) for future retrieval. This identifier can be anything, even thebundleID
of u’r app.kSecClass
:kSecClassKey
: Specifies that the object is a cryptographic key.kSecReturnData
:kCFBooleanTrue
: Ensures the raw key data is returned after creation. This is needed so we can start using it exactly after creation.
For private key settings will be same, except kSecAttrApplicationTag
.
Having this settings in place, we also must provide Key Pair Generation Parameters:
where:
kSecAttrKeyType
:kSecAttrKeyTypeRSA
: Specifies the key type as RSA.kSecAttrKeySizeInBits
:size
: Sets the key size (e.g., 2048 or 4096 bits) from the keySize property.kSecPublicKeyAttrs
andkSecPrivateKeyAttrs
: Links the previously defined attributes for public and private keys.
With this settings in place, we can generate the key-pair:
SecKeyCreateRandomKey
: Generates a new private key based on the parameters. If successful, it stores the private key in the Keychain.SecKeyCopyPublicKey
: Extracts the corresponding public key from the private key.- If either function fails, an exception is thrown using the
RSAProviderFailure.keyGenerationFailed
error (this is custom one, u may create u’r own).
And the last, but not least - create our keyPait object for future use:
There are could be some enchansment as:
Key Permissions
: Add attributes to restrict key usage (e.g., encryption only).Error Handling Improvements
: Safely unwrap and describe error for better debugging.Performance Testing
: Evaluate how key sizes affect performance and usability.
But for basic usage approach described above will be fully ok.
One more thing - retrieving key from keychain.
To do so, we must create a query for it, qury require some additional info:
where:
kSecClass
:kSecClassKey
: Specifies the type of object being queried, which is a cryptographic key (kSecClassKey
).kSecAttrApplicationTag
: A unique identifier (keyType can be .public or .private). This tag is used to distinguish the key being fetched.kSecAttrKeyType
:kSecAttrKeyTypeRSA
: Indicates that the key is an RSA key.kSecReturnRef
:kCFBooleanTrue
: Ensures the query returns a reference to the key (SecKey
) if found.SecItemCopyMatching
: Queries the Keychain for the key matching the specified attributes.- Return Value: The
status
variable contains the result of the query
encrypt/decrypt
Now, having our keys in place, we can start working on protection for our data - encrypting and decryption. Let’s wrap everything in type named RSACryptor
.
To create a method that can encrypts a plaintext string into ciphertext using an RSA public key and a specified encryption algorithm we will utilize Apple’s Security
framework.
The basic idea - select algorithm, keys and encrypt data:
The decrypt process is similar:
For more easy usage we may also need convinience functions to convert String
, Data
and SecKey
between each other. Because u retrieve keys from Keychain as a Data
and use SecKey
in the process. U also may need to send publickey
via network.
To do so, we can add some extensions:
To convert SecKey
into data:
U done! ;]
example
output:
public key - MIICCgK...ySPAk0CAwEAAQ==
private key - MIIJJwIBAA...7hROKkymQEMg==
message to encrypt - hello 1.2.3
msgEncryptedData - ROPAHEzf...ccpbaU6TVLmLyID4YrDXNZkg=
decrypted info - hello 1.2.3
Source code
The source code available here
Best Practices
- Always validate input sizes when encrypting or decrypting data with RSA to avoid errors.
- Use modern padding schemes like OAEP for enhanced security.
- Store private keys securely using Keychain with appropriate access controls.
- Regularly update encryption algorithms and key sizes as cryptographic standards evolve.
- Avoid hardcoding keys in your codebase; instead, use secure storage mechanisms.
Resources
- RSA Algorithm on Wikipedia: A comprehensive explanation of RSA encryption.
- Khan Academy: Cryptography: Interactive lessons on cryptographic principles.
- Practical Cryptography: Insights into real-world cryptographic systems.
Security
SecKey
- Security Framework Reference A detailed overview of the Security framework, covering topics like cryptographic operations, certificate handling, and Keychain management.
- Cryptographic Services Guide Explains concepts such as public-key encryption, symmetric cryptography, and secure storage using Apple’s Security framework.
- Encrypting and Decrypting Data Using Public and Private Keys Learn how to perform encryption, decryption, and signing using
SecKey
. - iOS Security Guide Understand Apple’s recommendations for secure app development.
- Introduction to RSA Cryptography Overview of RSA’s principles, including key generation, encryption, and decryption.
- RSA Demonstration Tool Experiment with RSA encryption and decryption online.
- Secure RSA Implementation in Swift A working example of how to implement RSA encryption and decryption in iOS.
- Using RSA Encryption in Swift Learn how to securely encrypt and decrypt messages in your app
- Cryptography Engineering By Bruce Schneier et al. A practical guide to implementing secure cryptographic systems.
- Handbook of Applied Cryptography A comprehensive resource for understanding cryptographic algorithms, including RSA.
- OpenSSL Project Command-line tools for generating RSA keys and testing encryption.
- SecKey Utilities on GitHub Helpful tools for working with
SecKey
objects and RSA operations. - Cryptographic Playground Experiment with different cryptographic algorithms, including RSA.
- A Beginner’s Guide to RSA in iOS A straightforward introduction to how RSA works and how to implement it in Swift.
- The State of RSA in Modern Cryptography A discussion of the current state of RSA security and key size recommendations.
Share on: