Skip to content

Latest commit

 

History

History
247 lines (195 loc) · 6.8 KB

README.md

File metadata and controls

247 lines (195 loc) · 6.8 KB

Sodium Carthage compatible

Swift-Sodium

Swift-Sodium provides a safe and easy to use interface to perform common cryptographic operations on iOS and OSX.

It leverages the Sodium library, and although Swift is the primary target, the framework can also be used in Objective C.

Swift-Sodium requires Swift 2.0 (introduced in Xcode 7).

Usage

Add Sodium.framework as a dependency to your project, and import the module:

import Sodium

The Sodium library itself doesn't have to be installed on the system: the repository already includes a precompiled library for armv7, armv7s, arm64, as well as for the iOS simulator.

The libsodium-ios.a file has been generated by the dist-build/ios.sh script. The libsodium-osx.a file has been generated by the dist-build/osx.sh script.

Running these scripts on Xcode 7.3 (7D175) on the revision 66045e682143c68288be45135ab47ec8d49b6554 of libsodium generate files identical to the ones present in this repository.

Public-key Cryptography

Authenticated Encryption

let sodium = Sodium()!
let aliceKeyPair = sodium.box.keyPair()!
let bobKeyPair = sodium.box.keyPair()!
let message = "My Test Message".dataUsingEncoding(NSUTF8StringEncoding)!

let encryptedMessageFromAliceToBob: NSData =
  sodium.box.seal(message,
                  recipientPublicKey: bobKeyPair.publicKey,
                  senderSecretKey: aliceKeyPair.secretKey)!

let messageVerifiedAndDecryptedByBob =
  sodium.box.open(encryptedMessageFromAliceToBob,
                  senderPublicKey: bobKeyPair.publicKey,
                  recipientSecretKey: aliceKeyPair.secretKey)

seal() automatically generates a nonce and prepends it to the ciphertext. open() extracts the nonce and decrypts the ciphertext.

The Box class also provides alternative functions and parameters to deterministically generate key pairs, to retrieve the nonce and/or the authenticator, and to detach them from the original message.

Anonymous Encryption (Sealed Boxes)

let sodium = Sodium()!
let bobKeyPair = sodium.box.keyPair()!
let message = "My Test Message".dataUsingEncoding(NSUTF8StringEncoding)!

let encryptedMessageToBob =
  sodium.box.seal(message, recipientPublicKey: bobKeyPair.publicKey)!

let messageDecryptedByBob =
  sodium.box.open(encryptedMessageToBob,
                  recipientPublicKey: bobKeyPair.publicKey,
                  recipientSecretKey: bobKeyPair.secretKey)

seal() generates an ephemeral keypair, uses the ephemeral secret key in the encryption process, combines the ephemeral public key with the ciphertext, then destroys the keypair. The sender can not decrypt the resulting ciphertext. open() extracts the public key and decrypts using the recipient's secret key. Message integrity is verified, but the sender's identity cannot be correlated to the ciphertext.

Public-key signatures

Detached signatures

let sodium = Sodium()!
let message = "My Test Message".dataUsingEncoding(NSUTF8StringEncoding)!
let keyPair = sodium.sign.keyPair()!
let signature = sodium.sign.signature(message, secretKey: keyPair.secretKey)!
if sodium.sign.verify(message,
                      publicKey: keyPair.publicKey,
                      signature: signature) {
  // signature is valid
}

Attached signatures

let sodium = Sodium()!
let message = "My Test Message".dataUsingEncoding(NSUTF8StringEncoding)!
let keyPair = sodium.sign.keyPair()!
let signedMessage = sodium.sign.sign(message, secretKey: keyPair.secretKey)!
if let unsignedMessage = sodium.sign.open(signedMessage, publicKey: keyPair.publicKey) {
  // signature is valid
}

Secret-key authenticated encryption

let sodium = Sodium()!
let message = "My Test Message".dataUsingEncoding(NSUTF8StringEncoding)!
let secretKey = sodium.secretBox.key()!
let encrypted: NSData = sodium.secretBox.seal(message, secretKey: secretKey)!
if let decrypted = sodium.secretBox.open(encrypted, secretKey: secretKey) {
  // authenticator is valid, decrypted contains the original message
}

Hashing

Deterministic hashing

let sodium = Sodium()!
let message = "My Test Message".dataUsingEncoding(NSUTF8StringEncoding)!
let h = sodium.genericHash.hash(message)

Keyed hashing

let sodium = Sodium()!
let message = "My Test Message".dataUsingEncoding(NSUTF8StringEncoding)!
let key = "Secret key".dataUsingEncoding(NSUTF8StringEncoding)!
let h = sodium.genericHash.hash(message, key: key)

Streaming

let sodium = Sodium()!
let message1 = "My Test ".dataUsingEncoding(NSUTF8StringEncoding)!
let message2 = "Message".dataUsingEncoding(NSUTF8StringEncoding)!
let key = "Secret key".dataUsingEncoding(NSUTF8StringEncoding)!
let stream = sodium.genericHash.initStream(key)!
stream.update(message1)
stream.update(message2)
let h = stream.final()

Short-output hashing (SipHash)

let sodium = Sodium()!
let message = "My Test Message".dataUsingEncoding(NSUTF8StringEncoding)!
let key = sodium.randomBytes.buf(sodium.shortHash.KeyBytes)!
let h = sodium.shortHash.hash(message, key: key)

Random numbers generation

let sodium = Sodium()!
let randomData = sodium.randomBytes.buf(1000)

Password hashing

Using Argon2i:

let sodium = Sodium()!
let password = "Correct Horse Battery Staple".dataUsingEncoding(NSUTF8StringEncoding)!
let hashedStr = sodium.pwHash.str(password,
  opsLimit: sodium.pwHash.OpsLimitInteractive,
  memLimit: sodium.pwHash.MemLimitInteractive)!

if sodium.pwHash.strVerify(hashedStr, passwd: password) {
  // Password matches the given hash string
} else {
  // Password doesn't match the given hash string
}

Utilities

Zeroing memory

let sodium = Sodium()!
var dataToZero: NSMutableData
sodium.utils.zero(dataToZero)

Constant-time comparison

let sodium = Sodium()!
let secret1: NSData
let secret2: NSData
let equality = sodium.utils.equals(secret1, secret2)

Constant-time hexadecimal encoding

let sodium = Sodium()!
let data: NSData
let hex = sodium.utils.bin2hex(data)

Hexadecimal decoding

let sodium = Sodium()!
let data1 = sodium.utils.hex2bin("deadbeef")
let data2 = sodium.utils.hex2bin("de:ad be:ef", ignore: " :")