ObjectivePGP is an implementation of OpenPGP protocol for iOS and macOS. OpenPGP is the most widely used email encryption standard. It is defined by the OpenPGP Working Group of the Internet Engineering Task Force (IETF).

Here is the blog post story.

Installation

Framework

ObjectivePGP comes with the Frameworks for the latest release.

  1. Download ObjectivePGP.framework or build a framework with the build-frameworks.sh script.
  2. Link framework with the target
    • Add ObjectivePGP.framework to "Link Binary With Libraries" list for the target. screen shot 2017-06-30 at 02 20 47
  3. Link libraries and frameworks
    1. Add Security.framework to "Link Binary With Libraries" list for the target. These are system libraries.
    2. Add libz and libbz2 to "Link Binary With Libraries" list for the target. These are system libraries.

Contribution

You are welcome to contribute. Please create Pull Request against develop branch.

Usage

Initialization
#include <ObjectivePGP/ObjectivePGP.h>

ObjectivePGP *pgp = [[ObjectivePGP alloc] init];
Load keys (private or public)
/* Import keys from a keyring file */
[pgp importKeysFromFile:@"/path/to/secring.gpg"];

/* Import keys from a keys file */
[pgp importKeysFromFile:@"/path/to/key.asc"];

/* Import selected key from a keyring */
[pgp importKey:@"979E4B03DFFE30C6" fromFile:@"/path/to/secring.gpg"];
Search for keys
/* long identifier 979E4B03DFFE30C6 */
PGPKey *key = [pgp findKeyForIdentifier:@"979E4B03DFFE30C6"];

/* Short identifier 979E4B03 (the same result as previous) */
PGPKey *key = [pgp findKeyForIdentifier:@"979E4B03"];

/* First key that match given user identifier string. */
PGPKey *key = [pgp findKeysForUserID:@"Name <email@example.com>"];
Export keys (private or public)
/* Export all public keys to file */
if ([pgp exportKeysOfType:PGPPartialKeyPublic toFile:@"pubring.gpg" error:nil]) {
    // success
}

/* Export single key */
/* export key and save as armored (ASCII) file */
PGPKey *key = [self.oPGP findKeyForIdentifier:@"979E4B03DFFE30C6"];
NSData *armoredKeyData = [pgp exportKey:key armored:YES];
[armoredKeyData writeToFile:@"pubkey.asc" atomically:YES];
Sign data (or file)
NSData *fileContent = [NSData dataWithContentsOfFile:@"/path/file/to/data.txt"];

/* Choose a key to use to sign the data */
PGPKey *key = [self.oPGP findKeyForIdentifier:@"979E4B03DFFE30C6"];

/* Sign and return only a signature data (detached = YES) */
NSData *signature = [pgp signData:fileContent usingKey:key passphrase:nil detached:YES error:nil];

/* Sign and return a data with the signature (detached = NO) */
NSData *signedData = [pgp signData:fileContent usingSecretKey:key passphrase:nil detached:NO error:nil];
Verify signature from data (or file)
/* embedded signature */
NSData *signedContent = [NSData dataWithContentsOfFile:@"/path/file/to/data.signed"];
if ([pgp verifyData:signedContent]) {
    // Success
}

/* detached signature */
NSData *signatureContent = [NSData dataWithContentsOfFile:@"/path/file/to/signature"];
NSData *dataContent = [NSData dataWithContentsOfFile:@"/path/file/to/data.txt"];
if ([pgp verifyData:dataContent withSignature:signatureContent]) {
    // Success
}
Encrypt data with previously loaded public key
NSData *fileContent = [NSData dataWithContentsOfFile:@"/path/plaintext.txt"];

/* Choose the public key to use to encrypt data. Must be imported previously */
PGPKey *key = [self.oPGP findKeyForIdentifier:@"979E4B03DFFE30C6"];

/* Encrypt data. Armor output (ASCII file)  */
NSData *encryptedData = [pgp encryptData:fileContent usingKeys:@[key] armored:YES error:nil];
if (encryptedData) {
    // Success
}
Decrypt data with previously loaded private key
NSData *encryptedFileContent = [NSData dataWithContentsOfFile:@"/path/data.enc"];

/* If key is encrypted with the password, you can provide a password key here. */
NSData *decryptedData = [pgp decryptData:encryptedFileContent passphrase:nil error:nil];
if (decryptedData) {
    // Success
}

Changelog

See CHANGELOG

Known limitations:

  • Embedded signatures are not supported.
  • ZIP compression not fully supported.
  • Blowfish, Twofish and Elgamal are not supported.
  • Missing external configuration for default values.

The license

The ObjectivePGP stays under a dual license:

  • Free for non-commercial use, covered by the standard 2-clause BSD license. That means you have to mention Marcin Krzyżanowski as the original author of this code and reproduce the LICENSE text inside your app.

  • Commercial-use license to use in commercial products. Please bear in mind that some free products remain commercial products. Please contact me via email for details.

Acknowledgment

This product uses software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)

Author

Marcin Krzyżanowski