Skip to content

Commit cf09559

Browse files
committed
Merge pull request #18 from andredsp/master
Use salt as an array of bytes instead of String
2 parents 24c1180 + 91f7ce3 commit cf09559

File tree

5 files changed

+55
-3
lines changed

5 files changed

+55
-3
lines changed

DemoPlayground.playground/section-1.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ sha1String
3131

3232
// MARK: - Key Digest Demo
3333
// Data from RFC 6070
34-
let tests = [ ("password", "salt", 1, 20, "0c60c80f961f0e71f3a9b524af6012062fe037a6")]
34+
let tests = [ ("password", "salt", 1, 20, "0c60c80f961f0e71f3a9b524af6012062fe037a6"),
35+
("password", arrayFromString("salt"), 1, 20, "0c60c80f961f0e71f3a9b524af6012062fe037a6")]
3536
for (password, salt, rounds, dkLen, expected) in tests
3637
{
3738
let key = PBKDF.deriveKey(password, salt: salt, prf: .SHA1, rounds: uint(rounds), derivedKeyLength: UInt(dkLen))

IDZSwiftCommonCrypto/KeyDerivation.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,28 @@ public class PBKDF
8080
return derivedKey
8181
}
8282

83+
///
84+
/// Derives key material from a password and salt.
85+
///
86+
/// -parameter password: the password string, will be converted using UTF8
87+
/// -parameter salt: the salt array of bytes
88+
/// -parameter prf: the pseudo random function
89+
/// -parameter round: the number of rounds
90+
/// -parameter derivedKeyLength: the length of the desired derived key, in bytes.
91+
/// -returns: the derived key
92+
///
93+
public class func deriveKey(password : String, salt : [UInt8], prf: PseudoRandomAlgorithm, rounds: uint, derivedKeyLength: UInt) -> [UInt8]
94+
{
95+
var derivedKey = Array<UInt8>(count:Int(derivedKeyLength), repeatedValue: 0)
96+
let status : Int32 = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), password, password.lengthOfBytesUsingEncoding(NSUTF8StringEncoding), salt, salt.count, prf.nativeValue(), rounds, &derivedKey, derivedKey.count)
97+
if(status != Int32(kCCSuccess))
98+
{
99+
NSLog("ERROR: CCKeyDerivationPBDK failed with stats \(status).")
100+
fatalError("ERROR: CCKeyDerivationPBDK failed.")
101+
}
102+
return derivedKey
103+
}
104+
83105
//MARK: - Low-level Routines
84106
///
85107
/// Derives key material from a password buffer.

IDZSwiftCommonCrypto/Utilities.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ public func arrayFromHexString(s : String) -> [UInt8]
4848
return a
4949
}
5050

51+
///
52+
/// Converts a Swift UTF-8 String to a Swift array.
53+
///
54+
/// - parameter s: the string
55+
/// - returns: a Swift array
56+
///
57+
public func arrayFromString(s : String) -> [UInt8]
58+
{
59+
let array = [UInt8](s.utf8)
60+
return array
61+
}
62+
5163
///
5264
/// Converts a string of hexadecimal digits to an `NSData` object.
5365
///

IDZSwiftCommonCryptoTests/IDZSwiftCommonCryptoTests.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,8 @@ class IDZSwiftCommonCryptoTests: XCTestCase {
470470
// MARK: - KeyDerivation tests
471471
// See: https://www.ietf.org/rfc/rfc6070.txt
472472
func test_KeyDerivation_deriveKey()
473-
{
473+
{
474+
// Tests with String salt
474475
let tests = [ ("password", "salt", 1, 20, "0c60c80f961f0e71f3a9b524af6012062fe037a6"),
475476
("password", "salt", 2, 20, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"),
476477
("password", "salt", 4096, 20, "4b007901b765489abead49d926f721d065a429c1"),
@@ -486,6 +487,22 @@ class IDZSwiftCommonCryptoTests: XCTestCase {
486487
XCTAssertEqual(key, arrayFromHexString(expected), "Obtained correct key (\(keyString) == \(expected)")
487488
}
488489

490+
// Tests with Array salt
491+
let tests2 = [ ("password", arrayFromString("salt"), 1, 20, "0c60c80f961f0e71f3a9b524af6012062fe037a6"),
492+
("password", arrayFromString("salt"), 2, 20, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"),
493+
("password", arrayFromString("salt"), 4096, 20, "4b007901b765489abead49d926f721d065a429c1"),
494+
// ("password", "salt", 16777216, 20, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984"),
495+
("passwordPASSWORDpassword", arrayFromString("saltSALTsaltSALTsaltSALTsaltSALTsalt"), 4096, 25, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"),
496+
("pass\0word", arrayFromString("sa\0lt"), 4096, 16, "56fa6aa75548099dcc37d7f03425e0c3"),
497+
]
498+
for (password, salt, rounds, dkLen, expected) in tests2
499+
{
500+
let key = PBKDF.deriveKey(password, salt: salt, prf: .SHA1, rounds: uint(rounds), derivedKeyLength: UInt(dkLen))
501+
let keyString = hexStringFromArray(key)
502+
503+
XCTAssertEqual(key, arrayFromHexString(expected), "Obtained correct key (\(keyString) == \(expected)")
504+
}
505+
489506
}
490507

491508
// MARK: - Random tests

README.playground/section-17.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
let keys6 = PBKDF.deriveKey("password", salt: "salt", prf: .SHA1, rounds: 1, derivedKeyLength: 20)
1+
let keys6 = PBKDF.deriveKey("password", salt: arrayFromString("salt"), prf: .SHA1, rounds: 1, derivedKeyLength: 20)
22
// RFC 6070 - Should derive 0c60c80f961f0e71f3a9b524af6012062fe037a6
33
let expectedRFC6070 = arrayFromHexString("0c60c80f961f0e71f3a9b524af6012062fe037a6")
44
assert(keys6 == expectedRFC6070)

0 commit comments

Comments
 (0)