|
@@ -1,14 +1,22 @@
|
|
|
[](#installation)
|
|
|
-[](#swift-versions-support)
|
|
|
-[](https://cocoapods.org/pods/CryptoSwift)
|
|
|
-[](https://github.com/Carthage/Carthage)
|
|
|
-[](https://github.com/apple/swift-package-manager)
|
|
|
-[](http://twitter.com/krzyzanowskim)
|
|
|
+[](#swift-versions-support)
|
|
|
+
|
|
|
+[](https://cocoapods.org/pods/CryptoSwift)
|
|
|
+[](https://github.com/Carthage/Carthage)
|
|
|
+[](https://github.com/apple/swift-package-manager)
|
|
|
+
|
|
|
+[](http://twitter.com/krzyzanowskim)
|
|
|
|
|
|
# CryptoSwift
|
|
|
|
|
|
Crypto related functions and helpers for [Swift](https://swift.org) implemented in Swift. ([#PureSwift](https://twitter.com/hashtag/pureswift))
|
|
|
|
|
|
+<hr />
|
|
|
+
|
|
|
+If you find the project useful, please [support authors](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=92Z6U3LBHF9J4) to keep it alive.
|
|
|
+
|
|
|
+<hr />
|
|
|
+
|
|
|
# Table of Contents
|
|
|
- [Requirements](#requirements)
|
|
|
- [Features](#features)
|
|
@@ -30,9 +38,6 @@ Good mood
|
|
|
- Support for incremental updates (stream, ...)
|
|
|
- iOS, macOS, AppleTV, watchOS, Linux support
|
|
|
|
|
|
-## Donation
|
|
|
-[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=92Z6U3LBHF9J4) to make the CryptoSwift awesome! Thank you.
|
|
|
-
|
|
|
#### Hash (Digest)
|
|
|
- [MD5](http://tools.ietf.org/html/rfc1321)
|
|
|
- [SHA1](http://tools.ietf.org/html/rfc3174)
|
|
@@ -63,7 +68,8 @@ Good mood
|
|
|
- Propagating Cipher Block Chaining ([PCBC](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Propagating_Cipher_Block_Chaining_.28PCBC.29))
|
|
|
- Cipher feedback ([CFB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_.28CFB.29))
|
|
|
- Output Feedback ([OFB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_Feedback_.28OFB.29))
|
|
|
-- Counter ([CTR](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29))
|
|
|
+- Counter Mode ([CTR](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29))
|
|
|
+- Galois/Counter Mode ([GCM](https://csrc.nist.gov/publications/detail/sp/800-38d/final))
|
|
|
|
|
|
#### Password-Based Key Derivation Function
|
|
|
- [PBKDF1](http://tools.ietf.org/html/rfc2898#section-5.1) (Password-Based Key Derivation Function 1)
|
|
@@ -77,16 +83,15 @@ Good mood
|
|
|
- No padding
|
|
|
|
|
|
#### Authenticated Encryption with Associated Data (AEAD)
|
|
|
-- [AEAD_CHACHA20_POLY1305](https://tools.ietf.org/html/rfc7539#section-2.8)
|
|
|
+- [AEAD\_CHACHA20\_POLY1305](https://tools.ietf.org/html/rfc7539#section-2.8)
|
|
|
|
|
|
## Why
|
|
|
[Why?](https://github.com/krzyzanowskim/CryptoSwift/issues/5) [Because I can](https://github.com/krzyzanowskim/CryptoSwift/issues/5#issuecomment-53379391).
|
|
|
|
|
|
## Contribution
|
|
|
|
|
|
-For the latest version, please check [develop](https://github.com/krzyzanowskim/CryptoSwift/tree/develop) branch. Changes from this branch will be merged into the [master](https://github.com/krzyzanowskim/CryptoSwift/tree/master) branch at some point.
|
|
|
+Check out [CONTRIBUTING.md](CONTRIBUTING.md) for more information on how to help with CryptoSwift.
|
|
|
|
|
|
-- If you want to contribute, submit a [pull request](https://github.com/krzyzanowskim/CryptoSwift/pulls) against a development `develop` branch.
|
|
|
- If you found a bug, [open an issue](https://github.com/krzyzanowskim/CryptoSwift/issues).
|
|
|
- If you have a feature request, [open an issue](https://github.com/krzyzanowskim/CryptoSwift/issues).
|
|
|
|
|
@@ -160,7 +165,7 @@ You can use [Swift Package Manager](https://swift.org/package-manager/) and spec
|
|
|
|
|
|
```swift
|
|
|
dependencies: [
|
|
|
- .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMinor(from: "0.8.0"))
|
|
|
+ .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMinor(from: "0.9.0"))
|
|
|
]
|
|
|
```
|
|
|
|
|
@@ -168,11 +173,13 @@ or more strict
|
|
|
|
|
|
```swift
|
|
|
dependencies: [
|
|
|
- .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .exact("0.8.0"))
|
|
|
+ .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .exact("0.9.0"))
|
|
|
]
|
|
|
```
|
|
|
|
|
|
See: [Package.swift - manual](http://blog.krzyzanowskim.com/2016/08/09/package-swift-manual/)
|
|
|
+
|
|
|
+---
|
|
|
|
|
|
## Usage
|
|
|
|
|
@@ -186,6 +193,7 @@ See: [Package.swift - manual](http://blog.krzyzanowskim.com/2016/08/09/package-s
|
|
|
* [Rabbit](#rabbit)
|
|
|
* [Blowfish](#blowfish)
|
|
|
* [Advanced Encryption Standard (AES)](#aes)
|
|
|
+* [AES-GCM](#aes-gcm)
|
|
|
* [Authenticated Encryption with Associated Data (AEAD)](#aead)
|
|
|
|
|
|
also check [Playground](/CryptoSwift.playground/Contents.swift)
|
|
@@ -332,8 +340,8 @@ let decrypted = try Rabbit(key: key, iv: iv).decrypt(encrypted)
|
|
|
##### Blowfish
|
|
|
|
|
|
```swift
|
|
|
-let encrypted = try Blowfish(key: key, blockMode: .CBC(iv: iv), padding: .pkcs7).encrypt(message)
|
|
|
-let decrypted = try Blowfish(key: key, blockMode: .CBC(iv: iv), padding: .pkcs7).decrypt(encrypted)
|
|
|
+let encrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(message)
|
|
|
+let decrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted)
|
|
|
```
|
|
|
|
|
|
##### AES
|
|
@@ -348,7 +356,7 @@ Variant of AES encryption (AES-128, AES-192, AES-256) depends on given key lengt
|
|
|
|
|
|
AES-256 example
|
|
|
```swift
|
|
|
-try AES(key: [1,2,3,...,32], blockMode: .CBC(iv: [1,2,3,...,16]), padding: .pkcs7)
|
|
|
+try AES(key: [1,2,3,...,32], blockMode: CBC(iv: [1,2,3,...,16]), padding: .pkcs7)
|
|
|
```
|
|
|
|
|
|
###### All at once
|
|
@@ -391,8 +399,8 @@ let key: Array<UInt8> = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
let iv: Array<UInt8> = AES.randomIV(AES.blockSize)
|
|
|
|
|
|
do {
|
|
|
- let encrypted = try AES(key: key, blockMode: .CBC(iv: iv), padding: .pkcs7).encrypt(input)
|
|
|
- let decrypted = try AES(key: key, blockMode: .CBC(iv: iv), padding: .pkcs7).decrypt(encrypted)
|
|
|
+ let encrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(input)
|
|
|
+ let decrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted)
|
|
|
} catch {
|
|
|
print(error)
|
|
|
}
|
|
@@ -402,7 +410,7 @@ AES without data padding
|
|
|
|
|
|
```swift
|
|
|
let input: Array<UInt8> = [0,1,2,3,4,5,6,7,8,9]
|
|
|
-let encrypted: Array<UInt8> = try! AES(key: Array("secret0key000000".utf8), blockMode: .CBC(iv: Array("0123456789012345".utf8)), padding: .noPadding).encrypt(input)
|
|
|
+let encrypted: Array<UInt8> = try! AES(key: Array("secret0key000000".utf8), blockMode: CBC(iv: Array("0123456789012345".utf8)), padding: .noPadding).encrypt(input)
|
|
|
```
|
|
|
|
|
|
Using convenience extensions
|
|
@@ -413,6 +421,38 @@ let encrypted = try! plain.encrypt(ChaCha20(key: key, iv: iv))
|
|
|
let decrypted = try! encrypted.decrypt(ChaCha20(key: key, iv: iv))
|
|
|
```
|
|
|
|
|
|
+##### AES-GCM
|
|
|
+
|
|
|
+The result of Galois/Counter Mode (GCM) encryption is ciphertext and **authentication tag**, that is later used to decryption.
|
|
|
+
|
|
|
+encryption
|
|
|
+
|
|
|
+```swift
|
|
|
+do {
|
|
|
+ let gcm = GCM(iv: iv)
|
|
|
+ let aes = try AES(key: key, blockMode: gcm, padding: .noPadding)
|
|
|
+ let encrypted = try aes.encrypt(plaintext)
|
|
|
+ let tag = gcm.authenticationTag
|
|
|
+catch {
|
|
|
+ // failed
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+decryption
|
|
|
+
|
|
|
+```swift
|
|
|
+do {
|
|
|
+ let gcm = GCM(iv: iv, authenticationTag: tag)
|
|
|
+ let aes = try AES(key: key, blockMode: gcm, padding: .noPadding)
|
|
|
+ return try aes.decrypt(encrypted)
|
|
|
+} catch {
|
|
|
+ // failed
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+Note: GCM instance is not intended to be reused. So you can't use the `GCM` from encoding, do decoding.
|
|
|
+
|
|
|
##### AEAD
|
|
|
|
|
|
```swift
|