sodocumentation.net Open in urlscan Pro
2a06:98c1:3120::3  Public Scan

Submitted URL: http://sodocumentation.net/swift/topic/7053/pbkdf2-key-derivation
Effective URL: https://sodocumentation.net/swift/topic/7053/pbkdf2-key-derivation
Submission: On September 15 via manual from VN — Scanned from NL

Form analysis 1 forms found in the DOM

POST https://zzzprojects.us9.list-manage.com/subscribe/post?u=cecbc4775cf67bf1ff82018af&id=98c3fcbe02

<form action="https://zzzprojects.us9.list-manage.com/subscribe/post?u=cecbc4775cf67bf1ff82018af&amp;id=98c3fcbe02" method="post" target="_blank">
  <input type="email" class="form-control" name="EMAIL" placeholder="Enter your email address">
  <button type="submit" class="btn btn-z">
    <i class="far fa-newspaper"></i>&nbsp;Subscribe </button>
</form>

Text Content

SO Documentation

 * Tags
 * Topics






SWIFT LANGUAGE

 * Getting started with Swift Language
 * (Unsafe) Buffer Pointers
 * Access Control
 * Advanced Operators
 * AES encryption
 * Algorithms with Swift
 * Arrays
 * Associated Objects
 * Blocks
 * Booleans
 * Caching on disk space
 * Classes
 * Closures
 * Completion Handler
 * Concurrency
 * Conditionals
 * Cryptographic Hashing
 * Dependency Injection
 * Design Patterns - Creational
 * Design Patterns - Structural
 * Dictionaries
 * Documentation markup
 * Enums
 * Error Handling
 * Extensions
 * Function as first class citizens in Swift
 * Functional Programming in Swift
 * Functions
 * Generate UIImage of Initials from String
 * Generics
 * Getting Started with Protocol Oriented Programming
 * Initializers
 * Logging in Swift
 * Loops
 * Memory Management
 * Method Swizzling
 * NSRegularExpression in Swift
 * Numbers
 * Optionals
 * OptionSet
 * PBKDF2 Key Derivation
 * Performance
 * Protocols
 * Reading & Writing JSON
 * Reflection
 * RxSwift
 * Sets
 * Strings and Characters
 * Structs
 * Style Conventions
 * Swift Advance functions
 * Swift HTTP server by Kitura
 * Swift Package Manager
 * Switch
 * The Defer Statement
 * Tuples
 * Type Casting
 * Typealias
 * Variables & Properties
 * Working with C and Objective-C




SWIFT LANGUAGE

 * Getting started with Swift Language
 * (Unsafe) Buffer Pointers
 * Access Control
 * Advanced Operators
 * AES encryption
 * Algorithms with Swift
 * Arrays
 * Associated Objects
 * Blocks
 * Booleans
 * Caching on disk space
 * Classes
 * Closures
 * Completion Handler
 * Concurrency
 * Conditionals
 * Cryptographic Hashing
 * Dependency Injection
 * Design Patterns - Creational
 * Design Patterns - Structural
 * Dictionaries
 * Documentation markup
 * Enums
 * Error Handling
 * Extensions
 * Function as first class citizens in Swift
 * Functional Programming in Swift
 * Functions
 * Generate UIImage of Initials from String
 * Generics
 * Getting Started with Protocol Oriented Programming
 * Initializers
 * Logging in Swift
 * Loops
 * Memory Management
 * Method Swizzling
 * NSRegularExpression in Swift
 * Numbers
 * Optionals
 * OptionSet
 * PBKDF2 Key Derivation
 * Performance
 * Protocols
 * Reading & Writing JSON
 * Reflection
 * RxSwift
 * Sets
 * Strings and Characters
 * Structs
 * Style Conventions
 * Swift Advance functions
 * Swift HTTP server by Kitura
 * Swift Package Manager
 * Switch
 * The Defer Statement
 * Tuples
 * Type Casting
 * Typealias
 * Variables & Properties
 * Working with C and Objective-C


SWIFT LANGUAGE PBKDF2 KEY DERIVATION



PASSWORD BASED KEY DERIVATION 2 (SWIFT 3)#

Password Based Key Derivation can be used both for deriving an encryption key
from password text and saving a password for authentication purposes.

There are several hash algorithms that can be used including SHA1, SHA256,
SHA512 which are provided by this example code.

The rounds parameter is used to make the calculation slow so that an attacker
will have to spend substantial time on each attempt. Typical delay values fall
in the 100ms to 500ms, shorter values can be used if there is unacceptable
performance.

This example requires Common Crypto
It is necessary to have a bridging header to the project:
#import <CommonCrypto/CommonCrypto.h>
Add the Security.framework to the project.

Parameters:

password     password String  
salt         salt Data  
keyByteCount number of key bytes to generate
rounds       Iteration rounds

returns      Derived key


func pbkdf2SHA1(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
    return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA1), password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)
}

func pbkdf2SHA256(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
    return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)
}

func pbkdf2SHA512(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
    return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)
}

func pbkdf2(hash :CCPBKDFAlgorithm, password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
    let passwordData = password.data(using:String.Encoding.utf8)!
    var derivedKeyData = Data(repeating:0, count:keyByteCount)

    let derivationStatus = derivedKeyData.withUnsafeMutableBytes {derivedKeyBytes in
        salt.withUnsafeBytes { saltBytes in

            CCKeyDerivationPBKDF(
                CCPBKDFAlgorithm(kCCPBKDF2),
                password, passwordData.count,
                saltBytes, salt.count,
                hash,
                UInt32(rounds),
                derivedKeyBytes, derivedKeyData.count)
        }
    }
    if (derivationStatus != 0) {
        print("Error: \(derivationStatus)")
        return nil;
    }

    return derivedKeyData
}


Example usage:

let password     = "password"
//let salt       = "saltData".data(using: String.Encoding.utf8)!
let salt         = Data(bytes: [0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let keyByteCount = 16
let rounds       = 100000

let derivedKey = pbkdf2SHA1(password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)
print("derivedKey (SHA1): \(derivedKey! as NSData)")


Example Output:

derivedKey (SHA1): <6b9d4fa3 0385d128 f6d196ee 3f1d6dbf>


PASSWORD BASED KEY DERIVATION 2 (SWIFT 2.3)#

See Swift 3 example for usage information and notes

func pbkdf2SHA1(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
    return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA1), password:password, salt:salt, keyCount:keyCount, rounds:UInt32(rounds))
}

func pbkdf2SHA256(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
    return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password:password, salt:salt, keyCount:keyCount, rounds:UInt32(rounds))
}

func pbkdf2SHA512(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
    return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), password:password, salt:salt, keyCount:keyCount, rounds:UInt32(rounds))
}

func pbkdf2(hash :CCPBKDFAlgorithm, password: String, salt: [UInt8], keyCount: Int, rounds: UInt32!) -> [UInt8]! {
    let derivedKey   = [UInt8](count:keyCount, repeatedValue:0)
    let passwordData = password.dataUsingEncoding(NSUTF8StringEncoding)!

    let derivationStatus = CCKeyDerivationPBKDF(
        CCPBKDFAlgorithm(kCCPBKDF2),
        UnsafePointer<Int8>(passwordData.bytes), passwordData.length,
        UnsafePointer<UInt8>(salt), salt.count,
        CCPseudoRandomAlgorithm(hash),
        rounds,
        UnsafeMutablePointer<UInt8>(derivedKey),
        derivedKey.count)


    if (derivationStatus != 0) {
        print("Error: \(derivationStatus)")
        return nil;
    }

    return derivedKey
}


Example usage:

let password = "password"
// let salt  = [UInt8]("saltData".utf8)
let salt     = [UInt8]([0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let rounds   = 100_000
let keyCount = 16

let derivedKey = pbkdf2SHA1(password, salt:salt, keyCount:keyCount, rounds:rounds)
print("derivedKey (SHA1):   \(NSData(bytes:derivedKey!, length:derivedKey!.count))")


Example Output:

derivedKey (SHA1):   <6b9d4fa3 0385d128 f6d196ee 3f1d6dbf>


PASSWORD BASED KEY DERIVATION CALIBRATION (SWIFT 2.3)#

See Swift 3 example for usage information and notes

func pbkdf2SHA1Calibrate(password:String, salt:[UInt8], msec:Int) -> UInt32 {
    let actualRoundCount: UInt32 = CCCalibratePBKDF(
        CCPBKDFAlgorithm(kCCPBKDF2),
        password.utf8.count,
        salt.count,
        CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1),
        kCCKeySizeAES256,
        UInt32(msec));
    return actualRoundCount
}


Example usage:

let saltData       = [UInt8]([0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let passwordString = "password"
let delayMsec      = 100

let rounds = pbkdf2SHA1Calibrate(passwordString, salt:saltData, msec:delayMsec)
print("For \(delayMsec) msec delay, rounds: \(rounds)")


Example Output:

> For 100 msec delay, rounds: 94339

PASSWORD BASED KEY DERIVATION CALIBRATION (SWIFT 3)#

Determine the number of PRF rounds to use for a specific delay on the current
platform.

Several parameters are defaulted to representative values that should not
materially affect the round count.

password Sample password.  
salt     Sample salt.  
msec     Targeted duration we want to achieve for a key derivation.

returns  The number of iterations to use for the desired processing time.


func pbkdf2SHA1Calibrate(password: String, salt: Data, msec: Int) -> UInt32 {
    let actualRoundCount: UInt32 = CCCalibratePBKDF(
        CCPBKDFAlgorithm(kCCPBKDF2),
        password.utf8.count,
        salt.count,
        CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1),
        kCCKeySizeAES256,
        UInt32(msec));
    return actualRoundCount
}


Example usage:

let saltData       = Data(bytes: [0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let passwordString = "password"
let delayMsec      = 100

let rounds = pbkdf2SHA1Calibrate(password:passwordString, salt:saltData, msec:delayMsec)
print("For \(delayMsec) msec delay, rounds: \(rounds)")


Example Output:

For 100 msec delay, rounds: 93457







AddThis Sharing Buttons
Share to FacebookFacebookFacebookShare to TwitterTwitterTwitterShare to
MoreAddThisMore

Previous Next








This modified text is an extract of the original Stack Overflow Documentation
created by following contributors and released under CC BY-SA 3.0
This website is not affiliated with Stack Overflow


SUPPORT & PARTNERS
 * Advertise with us
 * Contact us
 * Privacy Policy

STAY CONNECTED

Get monthly updates about new articles, cheatsheets, and tricks.

 Subscribe




x