Marcin Krzyżanowski 9 سال پیش
والد
کامیت
90054539a0
6فایلهای تغییر یافته به همراه132 افزوده شده و 17 حذف شده
  1. 3 0
      CHANGELOG
  2. 14 4
      CryptoSwift.xcodeproj/project.pbxproj
  3. 11 4
      CryptoSwiftTests/PBKDF.swift
  4. 4 1
      README.md
  5. 82 0
      Sources/CryptoSwift/PKCS5/PBKDF1.swift
  6. 18 8
      Sources/CryptoSwift/PKCS5/PBKDF2.swift

+ 3 - 0
CHANGELOG

@@ -1,3 +1,6 @@
+0.5
+- Added PBKDF2 https://tools.ietf.org/html/rfc2898#section-5.1
+
 0.4.1
 0.4.1
 - fix NoPadding()
 - fix NoPadding()
 
 

+ 14 - 4
CryptoSwift.xcodeproj/project.pbxproj

@@ -17,7 +17,7 @@
 		753881EC1CB06E390089101D /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753881EA1CB06E390089101D /* NoPadding.swift */; };
 		753881EC1CB06E390089101D /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753881EA1CB06E390089101D /* NoPadding.swift */; };
 		753881ED1CB06E390089101D /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753881EA1CB06E390089101D /* NoPadding.swift */; };
 		753881ED1CB06E390089101D /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753881EA1CB06E390089101D /* NoPadding.swift */; };
 		753881EE1CB06E390089101D /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753881EA1CB06E390089101D /* NoPadding.swift */; };
 		753881EE1CB06E390089101D /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753881EA1CB06E390089101D /* NoPadding.swift */; };
-		75482EA41CB310B7001F66A5 /* PBKDF2Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA31CB310B7001F66A5 /* PBKDF2Tests.swift */; };
+		75482EA41CB310B7001F66A5 /* PBKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA31CB310B7001F66A5 /* PBKDF.swift */; };
 		75482EA71CB329C1001F66A5 /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA61CB329C1001F66A5 /* PBKDF2.swift */; };
 		75482EA71CB329C1001F66A5 /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA61CB329C1001F66A5 /* PBKDF2.swift */; };
 		75482EA81CB329C1001F66A5 /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA61CB329C1001F66A5 /* PBKDF2.swift */; };
 		75482EA81CB329C1001F66A5 /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA61CB329C1001F66A5 /* PBKDF2.swift */; };
 		75482EA91CB329C1001F66A5 /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA61CB329C1001F66A5 /* PBKDF2.swift */; };
 		75482EA91CB329C1001F66A5 /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75482EA61CB329C1001F66A5 /* PBKDF2.swift */; };
@@ -227,6 +227,10 @@
 		75D0E05D1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
 		75D0E05D1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
 		75D0E05E1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
 		75D0E05E1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
 		75D0E05F1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
 		75D0E05F1CFB9B9400FCEA0E /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */; };
+		75D1F1F41D06B98B005A87A2 /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D1F1F31D06B98B005A87A2 /* PBKDF1.swift */; };
+		75D1F1F51D06B98B005A87A2 /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D1F1F31D06B98B005A87A2 /* PBKDF1.swift */; };
+		75D1F1F61D06B98B005A87A2 /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D1F1F31D06B98B005A87A2 /* PBKDF1.swift */; };
+		75D1F1F71D06B98B005A87A2 /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D1F1F31D06B98B005A87A2 /* PBKDF1.swift */; };
 		75DB81A31CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
 		75DB81A31CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
 		75DB81A41CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
 		75DB81A41CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
 		75DB81A51CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
 		75DB81A51CDBFDC700ED181A /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */; };
@@ -329,7 +333,7 @@
 		674A736E1BF5D85B00866C5B /* RabbitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RabbitTests.swift; sourceTree = "<group>"; };
 		674A736E1BF5D85B00866C5B /* RabbitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RabbitTests.swift; sourceTree = "<group>"; };
 		75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poly1305Tests.swift; sourceTree = "<group>"; };
 		75100F8E19B0BC890005C5F5 /* Poly1305Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poly1305Tests.swift; sourceTree = "<group>"; };
 		753881EA1CB06E390089101D /* NoPadding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NoPadding.swift; path = Sources/CryptoSwift/NoPadding.swift; sourceTree = SOURCE_ROOT; };
 		753881EA1CB06E390089101D /* NoPadding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NoPadding.swift; path = Sources/CryptoSwift/NoPadding.swift; sourceTree = SOURCE_ROOT; };
-		75482EA31CB310B7001F66A5 /* PBKDF2Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PBKDF2Tests.swift; sourceTree = "<group>"; };
+		75482EA31CB310B7001F66A5 /* PBKDF.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PBKDF.swift; sourceTree = "<group>"; };
 		75482EA61CB329C1001F66A5 /* PBKDF2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PBKDF2.swift; path = Sources/CryptoSwift/PKCS5/PBKDF2.swift; sourceTree = SOURCE_ROOT; };
 		75482EA61CB329C1001F66A5 /* PBKDF2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PBKDF2.swift; path = Sources/CryptoSwift/PKCS5/PBKDF2.swift; sourceTree = SOURCE_ROOT; };
 		75482EAB1CB329DF001F66A5 /* PKCS5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PKCS5.swift; path = Sources/CryptoSwift/PKCS5/PKCS5.swift; sourceTree = SOURCE_ROOT; };
 		75482EAB1CB329DF001F66A5 /* PKCS5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PKCS5.swift; path = Sources/CryptoSwift/PKCS5/PKCS5.swift; sourceTree = SOURCE_ROOT; };
 		754BE45519693E190098E6F3 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		754BE45519693E190098E6F3 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -392,6 +396,7 @@
 		75CB93481C8F60700087740D /* ECB.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ECB.swift; path = Sources/CryptoSwift/BlockMode/ECB.swift; sourceTree = SOURCE_ROOT; };
 		75CB93481C8F60700087740D /* ECB.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ECB.swift; path = Sources/CryptoSwift/BlockMode/ECB.swift; sourceTree = SOURCE_ROOT; };
 		75CB934D1C8F609D0087740D /* BlockModeOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BlockModeOptions.swift; path = Sources/CryptoSwift/BlockMode/BlockModeOptions.swift; sourceTree = SOURCE_ROOT; };
 		75CB934D1C8F609D0087740D /* BlockModeOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BlockModeOptions.swift; path = Sources/CryptoSwift/BlockMode/BlockModeOptions.swift; sourceTree = SOURCE_ROOT; };
 		75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Cipher.swift; path = Sources/CryptoSwift/Cipher.swift; sourceTree = SOURCE_ROOT; };
 		75D0E05B1CFB9B9400FCEA0E /* Cipher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Cipher.swift; path = Sources/CryptoSwift/Cipher.swift; sourceTree = SOURCE_ROOT; };
+		75D1F1F31D06B98B005A87A2 /* PBKDF1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PBKDF1.swift; path = Sources/CryptoSwift/PKCS5/PBKDF1.swift; sourceTree = SOURCE_ROOT; };
 		75D614BF1BD844F2001358B2 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		75D614BF1BD844F2001358B2 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BlockModeWorker.swift; path = Sources/CryptoSwift/BlockMode/BlockModeWorker.swift; sourceTree = SOURCE_ROOT; };
 		75DB81A21CDBFDC700ED181A /* BlockModeWorker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BlockModeWorker.swift; path = Sources/CryptoSwift/BlockMode/BlockModeWorker.swift; sourceTree = SOURCE_ROOT; };
 		75DB81A71CDC06B100ED181A /* Cryptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Cryptor.swift; path = Sources/CryptoSwift/Cryptor.swift; sourceTree = SOURCE_ROOT; };
 		75DB81A71CDC06B100ED181A /* Cryptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Cryptor.swift; path = Sources/CryptoSwift/Cryptor.swift; sourceTree = SOURCE_ROOT; };
@@ -450,6 +455,7 @@
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
 				75482EAB1CB329DF001F66A5 /* PKCS5.swift */,
 				75482EAB1CB329DF001F66A5 /* PKCS5.swift */,
+				75D1F1F31D06B98B005A87A2 /* PBKDF1.swift */,
 				75482EA61CB329C1001F66A5 /* PBKDF2.swift */,
 				75482EA61CB329C1001F66A5 /* PBKDF2.swift */,
 			);
 			);
 			name = PKCS5;
 			name = PKCS5;
@@ -538,7 +544,7 @@
 				674A736E1BF5D85B00866C5B /* RabbitTests.swift */,
 				674A736E1BF5D85B00866C5B /* RabbitTests.swift */,
 				755FB1D9199E347D00475437 /* ExtensionsTest.swift */,
 				755FB1D9199E347D00475437 /* ExtensionsTest.swift */,
 				757DA2521A4ED0A4002BA3EF /* PaddingTests.swift */,
 				757DA2521A4ED0A4002BA3EF /* PaddingTests.swift */,
-				75482EA31CB310B7001F66A5 /* PBKDF2Tests.swift */,
+				75482EA31CB310B7001F66A5 /* PBKDF.swift */,
 				756BFDCA1A82B87300B9D9A4 /* Bridging.h */,
 				756BFDCA1A82B87300B9D9A4 /* Bridging.h */,
 				754BE46519693E190098E6F3 /* Supporting Files */,
 				754BE46519693E190098E6F3 /* Supporting Files */,
 			);
 			);
@@ -862,6 +868,7 @@
 				757BC9891C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC9891C1CA5790093AAA9 /* MD5.swift in Sources */,
 				75DB81A91CDC06B100ED181A /* Cryptor.swift in Sources */,
 				75DB81A91CDC06B100ED181A /* Cryptor.swift in Sources */,
 				757BC9A91C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				757BC9A91C1CA5790093AAA9 /* SHA1.swift in Sources */,
+				75D1F1F51D06B98B005A87A2 /* PBKDF1.swift in Sources */,
 				757BC9911C1CA5790093AAA9 /* Operators.swift in Sources */,
 				757BC9911C1CA5790093AAA9 /* Operators.swift in Sources */,
 				75CB933B1C8F5FFD0087740D /* CFB.swift in Sources */,
 				75CB933B1C8F5FFD0087740D /* CFB.swift in Sources */,
 				757BC9B91C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
 				757BC9B91C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
@@ -923,6 +930,7 @@
 				757BC9881C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC9881C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC9A81C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				757BC9A81C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				75DB81A81CDC06B100ED181A /* Cryptor.swift in Sources */,
 				75DB81A81CDC06B100ED181A /* Cryptor.swift in Sources */,
+				75D1F1F41D06B98B005A87A2 /* PBKDF1.swift in Sources */,
 				757BC9901C1CA5790093AAA9 /* Operators.swift in Sources */,
 				757BC9901C1CA5790093AAA9 /* Operators.swift in Sources */,
 				75CB933A1C8F5FFD0087740D /* CFB.swift in Sources */,
 				75CB933A1C8F5FFD0087740D /* CFB.swift in Sources */,
 				757BC9B81C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
 				757BC9B81C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
@@ -945,7 +953,7 @@
 			isa = PBXSourcesBuildPhase;
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
-				75482EA41CB310B7001F66A5 /* PBKDF2Tests.swift in Sources */,
+				75482EA41CB310B7001F66A5 /* PBKDF.swift in Sources */,
 				758A94291A65C67400E46135 /* HMACTests.swift in Sources */,
 				758A94291A65C67400E46135 /* HMACTests.swift in Sources */,
 				75100F8F19B0BC890005C5F5 /* Poly1305Tests.swift in Sources */,
 				75100F8F19B0BC890005C5F5 /* Poly1305Tests.swift in Sources */,
 				757DA2571A4ED47B002BA3EF /* Helpers.swift in Sources */,
 				757DA2571A4ED47B002BA3EF /* Helpers.swift in Sources */,
@@ -1001,6 +1009,7 @@
 				757BC98A1C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC98A1C1CA5790093AAA9 /* MD5.swift in Sources */,
 				75DB81AB1CDC06B100ED181A /* Cryptor.swift in Sources */,
 				75DB81AB1CDC06B100ED181A /* Cryptor.swift in Sources */,
 				757BC9AA1C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				757BC9AA1C1CA5790093AAA9 /* SHA1.swift in Sources */,
+				75D1F1F71D06B98B005A87A2 /* PBKDF1.swift in Sources */,
 				757BC9921C1CA5790093AAA9 /* Operators.swift in Sources */,
 				757BC9921C1CA5790093AAA9 /* Operators.swift in Sources */,
 				75CB933C1C8F5FFD0087740D /* CFB.swift in Sources */,
 				75CB933C1C8F5FFD0087740D /* CFB.swift in Sources */,
 				757BC9BA1C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
 				757BC9BA1C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
@@ -1062,6 +1071,7 @@
 				757BC98B1C1CA5790093AAA9 /* MD5.swift in Sources */,
 				757BC98B1C1CA5790093AAA9 /* MD5.swift in Sources */,
 				75DB81AA1CDC06B100ED181A /* Cryptor.swift in Sources */,
 				75DB81AA1CDC06B100ED181A /* Cryptor.swift in Sources */,
 				757BC9AB1C1CA5790093AAA9 /* SHA1.swift in Sources */,
 				757BC9AB1C1CA5790093AAA9 /* SHA1.swift in Sources */,
+				75D1F1F61D06B98B005A87A2 /* PBKDF1.swift in Sources */,
 				757BC9931C1CA5790093AAA9 /* Operators.swift in Sources */,
 				757BC9931C1CA5790093AAA9 /* Operators.swift in Sources */,
 				75CB933D1C8F5FFD0087740D /* CFB.swift in Sources */,
 				75CB933D1C8F5FFD0087740D /* CFB.swift in Sources */,
 				757BC9BB1C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,
 				757BC9BB1C1CA5790093AAA9 /* UInt32Extension.swift in Sources */,

+ 11 - 4
CryptoSwiftTests/PBKDF2Tests.swift → CryptoSwiftTests/PBKDF.swift

@@ -1,5 +1,5 @@
 //
 //
-//  PBKDF2Tests.swift
+//  PBKDF.swift
 //  CryptoSwift
 //  CryptoSwift
 //
 //
 //  Created by Marcin Krzyzanowski on 04/04/16.
 //  Created by Marcin Krzyzanowski on 04/04/16.
@@ -9,7 +9,7 @@
 import XCTest
 import XCTest
 @testable import CryptoSwift
 @testable import CryptoSwift
 
 
-class PBKDF2Tests: XCTestCase {
+class PBKDF: XCTestCase {
 
 
     override func setUp() {
     override func setUp() {
         super.setUp()
         super.setUp()
@@ -19,10 +19,17 @@ class PBKDF2Tests: XCTestCase {
         super.tearDown()
         super.tearDown()
     }
     }
 
 
-    func test1() {
+    func test_pbkdf1() {
+        let password: [UInt8] = [0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64]
+        let salt: [UInt8] = [0x78,0x57,0x8E,0x5A,0x5D,0x63,0xCB,0x06]
+        let value = try! PKCS5.PBKDF1(password: password, salt: salt, iterations: 1000, keyLength: 16, variant: .sha1).calculate()
+        XCTAssertEqual(value.toHexString(), "dc19847e05c64d2faf10ebfb4a3d2a20")
+    }
+
+    func test_pbkdf2() {
         let password: [UInt8] = "s33krit".utf8.map {$0}
         let password: [UInt8] = "s33krit".utf8.map {$0}
         let salt: [UInt8] = "nacl".utf8.map {$0}
         let salt: [UInt8] = "nacl".utf8.map {$0}
-        let value = try! PKCS5.PBKDF2(password: password, salt: salt, iterations: 2, keyLength: 123, hashVariant: .sha1).calculate()
+        let value = try! PKCS5.PBKDF2(password: password, salt: salt, iterations: 2, keyLength: 123, variant: .sha1).calculate()
         XCTAssert(value.toHexString() == "a53cf3df485e5cd91c17c4978048e3ca86e03cced5f748fb55eff9c1edfce7f9f490c0beee768b85c1ba14ec5750cf059fea52565ffd9e4f9dba01c5c953955e7f1012b6a9eb40629ce767982e598df9081048e22781b35187c16d61ac43f69b88630a9e80233b4c58bdc74ea5c06b5bb1b2c2a86e3ddc2775b852c4508ac85a6a47c0e23a3d8dc6e4dca583", "PBKDF2 fail")
         XCTAssert(value.toHexString() == "a53cf3df485e5cd91c17c4978048e3ca86e03cced5f748fb55eff9c1edfce7f9f490c0beee768b85c1ba14ec5750cf059fea52565ffd9e4f9dba01c5c953955e7f1012b6a9eb40629ce767982e598df9081048e22781b35187c16d61ac43f69b88630a9e80233b4c58bdc74ea5c06b5bb1b2c2a86e3ddc2775b852c4508ac85a6a47c0e23a3d8dc6e4dca583", "PBKDF2 fail")
     }
     }
 
 

+ 4 - 1
README.md

@@ -201,7 +201,10 @@ let hmac: [UInt8] = try! Authenticator.HMAC(key: key, variant: .sha256).authenti
 let password: [UInt8] = "s33krit".utf8.map {$0}
 let password: [UInt8] = "s33krit".utf8.map {$0}
 let salt: [UInt8] = "nacl".utf8.map {$0}
 let salt: [UInt8] = "nacl".utf8.map {$0}
 
 
-let value = try! PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, hashVariant: .sha256).calculate()
+let value = try! PKCS5.PBKDF1(password: password, salt: salt, iterations: 4096, variant: .sha1).calculate()
+
+let value = try! PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, variant: .sha256).calculate()
+
 value.toHexString() // print Hex representation
 value.toHexString() // print Hex representation
 ```
 ```
 
 

+ 82 - 0
Sources/CryptoSwift/PKCS5/PBKDF1.swift

@@ -0,0 +1,82 @@
+//
+//  PBKDF1.swift
+//  CryptoSwift
+//
+//  Created by Marcin Krzyzanowski on 07/06/16.
+//  Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
+//
+
+public extension PKCS5 {
+
+    /// A key derivation function.
+    ///
+    /// PBKDF1 is recommended only for compatibility with existing
+    /// applications since the keys it produces may not be large enough for
+    /// some applications.
+    public struct PBKDF1 {
+
+        public enum Error: ErrorType {
+            case InvalidInput
+            case DerivedKeyTooLong
+        }
+
+        public enum Variant {
+            case md5, sha1
+
+            var size:Int {
+                switch (self) {
+                case .md5:
+                    return MD5.size
+                case .sha1:
+                    return SHA1.size
+                }
+            }
+
+            private func calculateHash(bytes bytes:[UInt8]) -> [UInt8]? {
+                switch (self) {
+                case .sha1:
+                    return Hash.sha1(bytes).calculate()
+                case .md5:
+                    return Hash.md5(bytes).calculate()
+                }
+            }
+        }
+
+        private let iterations: Int // c
+        private let variant: Variant
+        private let keyLength: Int
+        private let t1: [UInt8]
+
+        /// - parameters:
+        ///   - salt: salt, an eight-bytes
+        ///   - variant: hash variant
+        ///   - iterations: iteration count, a positive integer
+        ///   - keyLength: intended length of derived key
+        public init(password: [UInt8], salt: [UInt8], variant: Variant = .sha1, iterations: Int = 4096 /* c */, keyLength: Int? = nil /* dkLen */) throws {
+            precondition(iterations > 0)
+            precondition(salt.count == 8)
+
+            if (keyLength > variant.size) {
+                throw Error.DerivedKeyTooLong
+            }
+
+            guard let t1 = variant.calculateHash(bytes: password + salt) else {
+                throw Error.InvalidInput
+            }
+
+            self.iterations = iterations
+            self.variant = variant
+            self.keyLength = keyLength ?? variant.size
+            self.t1 = t1
+        }
+
+        /// Apply the underlying hash function Hash for c iterations
+        public func calculate() -> [UInt8] {
+            var t = t1
+            for _ in 2...self.iterations {
+                t = self.variant.calculateHash(bytes: t)!
+            }
+            return Array(t[0..<self.keyLength])
+        }
+    }
+}

+ 18 - 8
Sources/CryptoSwift/PKCS5/PBKDF2.swift

@@ -7,28 +7,38 @@
 //
 //
 
 
 public extension PKCS5 {
 public extension PKCS5 {
-    // PBKDF2 - Password-Based Key Derivation Function 2. Key stretching technique.
-    //          DK = PBKDF2(PRF, Password, Salt, c, dkLen)
+    /// A key derivation function.
+    ///
+    /// PBKDF2 - Password-Based Key Derivation Function 2. Key stretching technique.
+    ///          DK = PBKDF2(PRF, Password, Salt, c, dkLen)
     public struct PBKDF2 {
     public struct PBKDF2 {
 
 
         public enum Error: ErrorType {
         public enum Error: ErrorType {
             case InvalidInput
             case InvalidInput
+            case DerivedKeyTooLong
         }
         }
 
 
-        private let salt: [UInt8]
+        private let salt: [UInt8]   // S
         private let iterations: Int // c
         private let iterations: Int // c
-        private let numBlocks: UInt  // l
+        private let numBlocks: UInt // l
         private let prf: HMAC
         private let prf: HMAC
 
 
-        public init(password: [UInt8], salt: [UInt8], iterations: Int = 4096 /* c */, keyLength: Int? = nil /* dkLen */ , hashVariant: HMAC.Variant = .sha256) throws {
-            guard let prf = HMAC(key: password, variant: hashVariant) where (iterations > 0) && (password.count > 0) && (salt.count > 0) else {
+        /// - parameters:
+        ///   - salt: salt
+        ///   - variant: hash variant
+        ///   - iterations: iteration count, a positive integer
+        ///   - keyLength: intended length of derived key
+        public init(password: [UInt8], salt: [UInt8], iterations: Int = 4096 /* c */, keyLength: Int? = nil /* dkLen */, variant: HMAC.Variant = .sha256) throws {
+            precondition(iterations > 0)
+            
+            guard let prf = HMAC(key: password, variant: variant) where iterations > 0 && password.count > 0 && salt.count > 0 else {
                 throw Error.InvalidInput
                 throw Error.InvalidInput
             }
             }
 
 
-            let keyLengthFinal = Double(keyLength ?? hashVariant.size)
+            let keyLengthFinal = Double(keyLength ?? variant.size)
             let hLen = Double(prf.variant.size)
             let hLen = Double(prf.variant.size)
             if keyLengthFinal > (pow(2,32) - 1) * hLen {
             if keyLengthFinal > (pow(2,32) - 1) * hLen {
-                throw Error.InvalidInput
+                throw Error.DerivedKeyTooLong
             }
             }
 
 
             self.salt = salt
             self.salt = salt