Operations/QCCPBKDF2SHAKeyDerivation.h
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Derives a key from a password string using the PBKDF2 algorithm. |
*/ |
@import Foundation; |
NS_ASSUME_NONNULL_BEGIN |
/*! Denotes a specific SHA digest algorithm used internally the key derivation. |
* \warning SHA1 may not secure; if you have a choice, choose SHA2-256 or better. |
*/ |
typedef NS_ENUM(NSInteger, QCCPBKDF2SHAKeyDerivationAlgorithm) { |
QCCPBKDF2SHAKeyDerivationAlgorithmSHA1, |
QCCPBKDF2SHAKeyDerivationAlgorithmSHA2_224, |
QCCPBKDF2SHAKeyDerivationAlgorithmSHA2_256, |
QCCPBKDF2SHAKeyDerivationAlgorithmSHA2_384, |
QCCPBKDF2SHAKeyDerivationAlgorithmSHA2_512 |
}; |
/*! Derives a key from a password string using the PBKDF2 algorithm. |
* \details One key aspect of PBKDF2 is that it takes a significant amount of time to calculate the |
* key from the password, which helps to defeat brute force attacks. This time is proportional |
* to the number of 'rounds' done by PBKDF2. To get the best security, you should set 'rounds' |
* as high as you can such that PBKDF2 in a reasonable amount of time on your target hardware. |
* |
* This operation facilitates this by allowing you to specify a target derivation time. The |
* operation will automatically set the rounds parameter so that key derivation takes that |
* amount of time on the current hardware. It will also return the number of rounds taken, |
* so you can save that away along with the key and the salt. |
* |
* \warning You should *always* set the salt to some random data and save that random data along |
* with the key. This a) ensures that users with the same password don't end up using the same |
* key, and b) as a consequence of this, protects from rainbow table attacks. |
* |
* \details To use this operation, first generate a key: |
* |
* 1. use a cryptographically sound random number generator to generate some salt data |
* |
* 2. initialise the object with the required parameters, including that random salt |
* |
* 3. set `derivationTime` to a reasonable derivation time for a typical user login |
* |
* 4. run the operation |
* |
* 5. save the salt, the actual rounds and the derived key |
* |
* When the user tries to log in you can run the operation again: |
* |
* 1. initialise the object with the required parameters, where the password string |
* is the string the user entered and the salt is the salt you saved with the key |
* |
* 2. set the operation's rounds to be rounds you saved with the key |
* |
* 3. run the operation |
* |
* 4. get the derived key and compare it to your saved key |
*/ |
@interface QCCPBKDF2SHAKeyDerivation : NSOperation |
/*! Initialise the object to derive a key from the specified password.. |
* \param algorithm The specific SHA digest algorithm to use for the key derivation. |
* \param passwordString The password string from which to derive a key; may be empty. |
* \param saltData Some random data to salt the key derivation. |
* \returns The initialised object. |
*/ |
- (instancetype)initWithAlgorithm:(QCCPBKDF2SHAKeyDerivationAlgorithm)algorithm passwordString:(NSString *)passwordString saltData:(NSData *)saltData NS_DESIGNATED_INITIALIZER; |
- (instancetype)init NS_UNAVAILABLE; |
/*! The specific SHA digest algorithm to use for the key derivation. |
* \details This is set by the init method. |
*/ |
@property (atomic, assign, readonly ) QCCPBKDF2SHAKeyDerivationAlgorithm algorithm; |
/*! The password string from which to derive a key |
* \details This is set by the init method. |
*/ |
@property (atomic, copy, readonly ) NSString * passwordString; |
/*! Some random data to salt the key derivation. |
* \details This is set by the init method. |
*/ |
@property (atomic, copy, readonly ) NSData * saltData; |
/*! The number of rounds to use for the key derivation. |
* \details The default value is 0, which tells the operation to automatically calculate the |
* numbers of rounds based on `derivationTime`. That's a good choice when deriving a new |
* key. When checking a key you should set this to the number of rounds that were used |
* to derive the original key. |
* |
* If you set this, you must set it before queuing the operation. |
*/ |
@property (atomic, assign, readwrite) NSInteger rounds; |
/*! The target key derivation time. |
* \details If `rounds` is 0, this value is used as a target key derivation time; otherwise, |
* this value is ignored. The default is 0.1 seconds. |
* |
* The underlying API accepts this key derivation time as a `uint32_t` number of |
* milliseconds. This means that values less than 1 ms or greater than 0xFFFFFFFF |
* milliseconds are silently clipped. |
* |
* If you set this, you must set it before queuing the operation. |
*/ |
@property (atomic, assign, readwrite) NSTimeInterval derivationTime; |
/*! The size of the derived key. |
* \details The default is 16 bytes. |
* |
* If you set this, you must set it before queuing the operation. |
*/ |
@property (atomic, assign, readwrite) NSInteger derivedKeyLength; |
/*! The error, if any, resulting from key derivation operation. |
* \details This is set when the operation is finished. On success, it will be nil. Or error, |
* it will hold a value describing that error. You should expect errors to be in the |
* `QCCPBKDF2KeyDerivationErrorDomain` error domain. |
*/ |
@property (atomic, copy, readonly, nullable) NSError * error; |
/*! The number of rounds used to derive the key. |
* \details This is only meaningful when the operation has finished without error. If `rounds` |
* was non-zero, this will be equal to it. If `rounds` was 0, this will be the actual number |
* of rounds used to derive the key based on the target time set via `derivationTime`. |
*/ |
@property (atomic, assign, readonly) NSInteger actualRounds; |
/*! The derived key. |
* \details This is only meaningful when the operation has finished without error. The length |
* of this key will match `derivedKeyLength`. |
*/ |
@property (atomic, copy, readonly, nullable) NSData * derivedKeyData; |
@end |
/*! The error domain for the QCCPBKDF2SHAKeyDerivation operation. |
* \details Codes are Common Crypto error codes, that is, `kCCParamError` and its friends. |
*/ |
extern NSString * QCCPBKDF2KeyDerivationErrorDomain; |
NS_ASSUME_NONNULL_END |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-11-17