All Projects → etienne-martin → WebCrypto.swift

etienne-martin / WebCrypto.swift

Licence: other
A small collection of cryptographic functions based on the JavaScript WebCrypto API.

Programming Languages

swift
15916 projects
HTML
75241 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to WebCrypto.swift

jscrypto
Crypto library for Node/ES6/Typescript/Browser.
Stars: ✭ 20 (+25%)
Mutual labels:  aes, cipher, openssl, hash, sha256, sha512
hash-checker
Fast and simple application that allows you to generate and compare hashes from files and text
Stars: ✭ 72 (+350%)
Mutual labels:  hash, sha1, sha256, sha512, sha384
Checksum
Checksum calculation extensions for Swift
Stars: ✭ 28 (+75%)
Mutual labels:  digest, sha1, sha256, sha512, sha384
Forge
A native implementation of TLS in Javascript and tools to write crypto-based and network-heavy webapps
Stars: ✭ 4,204 (+26175%)
Mutual labels:  aes, cipher, sha1, sha256
hediye
Hash Generator & Cracker
Stars: ✭ 40 (+150%)
Mutual labels:  sha1, sha256, sha512, sha384
fhash
fHash - an open source files hash calculator for Windows and macOS
Stars: ✭ 222 (+1287.5%)
Mutual labels:  hash, sha1, sha256, sha512
hash-wasm
Lightning fast hash functions using hand-tuned WebAssembly binaries
Stars: ✭ 382 (+2287.5%)
Mutual labels:  hash, sha1, sha256, sha512
Cryptoswift
CryptoSwift is a growing collection of standard and secure cryptographic algorithms implemented in Swift
Stars: ✭ 8,846 (+55187.5%)
Mutual labels:  aes, cipher, digest, sha1
crypto.js
base on crypto module
Stars: ✭ 13 (-18.75%)
Mutual labels:  aes, sha1, sha256
Gtkhash
A cross-platform desktop utility for computing message digests or checksums
Stars: ✭ 167 (+943.75%)
Mutual labels:  hash, sha1, sha256
BruteForce
A simple brute forcer written in GO for SHA1, SHA256, SHA512, MD5 and bcrypt
Stars: ✭ 49 (+206.25%)
Mutual labels:  hash, sha1, sha256
Merkle
Node.js module implementing Merkle tree algorithm
Stars: ✭ 123 (+668.75%)
Mutual labels:  hash, sha1, sha256
Digestpp
C++11 header-only message digest library
Stars: ✭ 116 (+625%)
Mutual labels:  hash, sha1, sha256
Wjcryptlib
Public Domain C Library of Cryptographic functions. Including: MD5, SHA1, SHA256, SHA512, RC4, AES, AES-CTR, AES-OFB, AES-CBC
Stars: ✭ 250 (+1462.5%)
Mutual labels:  aes, sha1, sha256
Hashcobra
HashCobra Hash Cracking tool.
Stars: ✭ 96 (+500%)
Mutual labels:  hash, sha1, sha256
crypthash-net
CryptHash.NET is a .NET multi-target library to encrypt/decrypt/hash/encode/decode strings and files, with an optional .NET Core multiplatform console utility.
Stars: ✭ 33 (+106.25%)
Mutual labels:  aes, hash, decryption
Digestif
Simple hash algorithms in OCaml
Stars: ✭ 69 (+331.25%)
Mutual labels:  hash, sha1, sha256
ngx http hmac secure link module
HMAC Secure Link module for NGINX.
Stars: ✭ 47 (+193.75%)
Mutual labels:  openssl, hash, sha512
dtls
Datagram Transport Layer Security (DTLS) client.
Stars: ✭ 72 (+350%)
Mutual labels:  aes, sha256, sha384
Crypto Es
A cryptography algorithms library
Stars: ✭ 65 (+306.25%)
Mutual labels:  aes, sha1, sha256

WebCrypto.swift

A small collection of cryptographic functions based on the JavaScript WebCrypto API. Allows you to share the same crypto between a native iOS/OSX application and a web application.

The story

The original CryptoJS.swift library was developed in 2015 as I needed a way to share the same cryptography between a Swift application and a web app. My goal was achieved by using the same JavaScript CryptoJS library in both environments. CryptoJS is no longer maintained and suffers severe performance limitations over the new WebCrypto API.

This project leverages the power of the WebCrypto API while keeping backwards compatibility with CryptoJS.swift. All methods are asynchronous and run on a separate thread.

Performance

In comparison with other available solutions, here are the results obtained when encrypting a 10MB file with AES-256 on a 2.6 GHz Intel Core i7.

RNCryptor 92ms
openSSL: 139ms
WebCrypto.swift: 1545ms
CryptoSwift: 5255ms

Usage

  1. Drag and drop WebCrypto.swift and WebCrypto.js into your Xcode project.
  2. Initialize the WebCrypto class in your code:
let crypto = WebCrypto()
  1. That's it. No bridging header required.

Data types conversion

WebCrypto.swift works with Swift's Data object. If you need to pass a string to a method, you first need to convert it to Data before passing it as an input.

Convert String to Data:

let data = Data("This is a string".utf8)

Convert Data to String:

let string = String(data: data, encoding: .utf8)

Convert Data to hex encoded string:

let hex = crypto.hexEncodedStringFromData(data)

Convert hex encoded string to Data:

let data = crypto.dataFromHexEncodedString(hex)

Convert Data to base64 string:

let base64 = data.base64EncodedString(options: [])

Convert base64 string to Data:

let data = Data(base64Encoded: base64, options: .ignoreUnknownCharacters)

AES

The algorithm used by WebCrypto.swift is the cipher-block chaining (CBC) mode. For key generation, it uses PKCS7 as the padding method.

WebCrypto.swift supports AES-128, AES-192, and AES-256. It will pick the variant by the size of the key you pass in. If you use a password, AES-256 will be used.

Password-based encryption

WebCrypto.swift uses a salted key derivation algorithm. The salt is a piece of random bytes which are generated when encrypting, and stored in the file header; upon decryption, the salt is retrieved from the header, and the key and IV are recomputed from the provided password and the salt value.

The key derivation algorithm is the same as the one used by openSSL, making it compatible with openSSL and other libraries like CryptoJS.

Encryption
let input = Data("This is a string".utf8)

let password = "password123"

crypto.encrypt(data: input, password: password, callback: {(encrypted: Data?, error: Error?) in
    print(encrypted!)
})
Decryption
crypto.decrypt(data: encrypted, password: password, callback: {(decrypted: Data?, error: Error?) in
    print(String(data: decrypted!, encoding: .utf8)!)
})

Key-based encryption

This method requires a key and an IV in hexadecimal format. Use the generateKey and generateIv methods if you need to generate a new key and IV. Remember to never re-use an initialization vector. Always generate a new IV every time you encrypt.

Encryption
let input = Data("This is a string".utf8)

let key = "6f0f1c6f0e56afd327ff07b7b63a2d8ae91ab0a2f0c8cd6889c0fc1d624ac1b8"
let iv = "92c9d2c07a9f2e0a0d20710270047ea2"

crypto.encrypt(data: input, key: key, iv: iv, callback: {(encrypted: Data?, error: Error?) in
    print(encrypted!)
})
Decryption
crypto.decrypt(data: encrypted, key: key, iv: iv, callback: {(encrypted: Data?, error: Error?) in
    print(String(data: decrypted!, encoding: .utf8)!)
})

Encryption keys

This method generates 128, 192, or 256-bit hex-encoded keys. If the length parameter is omitted, the output is a 256-bit key by default.

crypto.generateKey(callback: {(key: String?, error: Error?) in
    print(key!) // aacdc64d6a3f88617af1ce43666970f0e915372cadda8ecb992d215b282a8c17
})

crypto.generateKey(length: 192, callback: {(key: String?, error: Error?) in
    print(key!) // 8c675b785838af61c4803c84fe3ba858a4556bdfcafc6c33
})

crypto.generateKey(length: 128, callback: {(key: String?, error: Error?) in
    print(key!) // dc1afda2e1bc5f9bd513a658b853cdec
})

Initialization vectors

This method generates a 16-bit hex-encoded IV. Remember to never re-use an initialization vector. Always generate a new IV every time you encrypt.

crypto.generateIv(callback: {(iv: String?, error: Error?) in
    print(iv!) // a408350a6ef6ceb8883173778d700b0a
})

Cryptographically secure number generator

This method lets you get cryptographically strong random values. The output is a hex-encoded string. Do not generate keys using this method. Use the generateKey method instead.

crypto.generateRandomNumber(length: 16, callback: {(number: String?, error: Error?) in
    print(number!) // aca73dd1c406bf498f1c07a3d607da9f
})

Hash functions

These methods compute the hash of a data object and output its hexadecimal digest.

let input = Data("This is a string".utf8)

crypto.sha1(data: input, callback: {(hash: String?, error: Error?) in
    print(hash!) // 8332d2a25bf1a039d8d296a7b7513960b191d95a
})

crypto.sha256(data: input, callback: {(hash: String?, error: Error?) in
    print(hash!) // a2a0d2d2f3046785436e99dcdc0a2a31b41555eed11750e0067b177b99b6c435
})

crypto.sha384(data: input, callback: {(hash: String?, error: Error?) in
    print(hash!) // e17d41b167194e4836c63bf3cdcf15b2478cb6fda5887485d5f568c98ed45e3a9bab16e7fe68aa8fe14f683f1144fb3a
})

crypto.sha512(data: input, callback: {(hash: String?, error: Error?) in
    print(hash!) // bc5d1ce2a9287ab94f1ed7eff379fbdab5e10d79f8f9dc4f921a2511f418e84561c8d6f63120cd960ea1f48afe09b3bffe2232bb920cc78a2bc873e05e76b30c
})

Error handling

Check whether the error value is non-nil to know if an error has occurred.

let input = Data("This is a string".utf8)

let password = "password123"

crypto.encrypt(data: input, password: password, callback: {(encrypted: Data?, error: Error?) in
    if let errorMessage = error {
        // Something went wrong
        print(errorMessage)
    }else{
        // Success
        print(encrypted!)
    }
})

Built with

  • WebCryptoAPI - JavaScript API for performing basic cryptographic operations
  • Forge - Used for the openSSL key derivation function
  • SparkMD5 - Used for the openSSL key derivation function

Contributing

When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.

Update the README.md with details of changes to the library.

Update the examples by demonstrating the changes to the library.

Build the project and test all the features before submitting your pull request.

Authors

License

This project is licensed under the MIT License - see the LICENSE file for details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].