Skip to content

Commit

Permalink
fix: Update PBKDF2 default iterations to OWASP latest recomendation
Browse files Browse the repository at this point in the history
chore: Update PBKDF2 linux's implementation to Crypto
chore: Use direct RSA initializer from primes
  • Loading branch information
amosavian committed Nov 2, 2024
1 parent 8ac705c commit 4556362
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 40 deletions.
14 changes: 6 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.8
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand All @@ -25,9 +25,9 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/Flight-School/AnyCodable", .upToNextMajor(from: "0.6.7")),
.package(url: "https://github.com/apple/swift-asn1.git", .upToNextMajor(from: "1.2.0")),
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "3.7.1")),
.package(url: "https://github.com/apple/swift-certificates", .upToNextMajor(from: "1.5.0")),
.package(url: "https://github.com/apple/swift-asn1.git", .upToNextMajor(from: "1.3.0")),
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "3.9.0")),
.package(url: "https://github.com/apple/swift-certificates", .upToNextMajor(from: "1.6.1")),
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMajor(from: "1.8.2")),
.package(url: "https://github.com/tsolomko/SWCompression.git", .upToNextMajor(from: "4.8.6")),
],
Expand Down Expand Up @@ -56,11 +56,9 @@ let package = Package(
)

for target in package.targets {
var swiftSettings: [SwiftSetting] = [
let swiftSettings: [SwiftSetting] = [
.enableExperimentalFeature("StrictConcurrency=complete"),
.enableUpcomingFeature("ExistentialAny")
]
#if swift(>=5.9)
swiftSettings.append(.enableUpcomingFeature("ExistentialAny"))
#endif
target.swiftSettings = swiftSettings
}
6 changes: 3 additions & 3 deletions Package@swift-6.0.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/Flight-School/AnyCodable", .upToNextMajor(from: "0.6.7")),
.package(url: "https://github.com/apple/swift-asn1.git", .upToNextMajor(from: "1.2.0")),
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "3.7.1")),
.package(url: "https://github.com/apple/swift-certificates", .upToNextMajor(from: "1.5.0")),
.package(url: "https://github.com/apple/swift-asn1.git", .upToNextMajor(from: "1.3.0")),
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "3.9.0")),
.package(url: "https://github.com/apple/swift-certificates", .upToNextMajor(from: "1.6.1")),
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMajor(from: "1.8.2")),
.package(url: "https://github.com/tsolomko/SWCompression.git", .upToNextMajor(from: "4.8.6")),
],
Expand Down
28 changes: 20 additions & 8 deletions Sources/JWSETKit/Cryptography/RSA/RSA.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ extension _RSA.Signing.PublicKey: JSONWebValidatingKey {
}

public static func create(storage: JSONWebValueStorage) throws -> _RSA.Signing.PublicKey {
let der = try RSAHelper.pkcs1Representation(AnyJSONWebKey(storage: storage))
return try .init(derRepresentation: der)
let key = AnyJSONWebKey(storage: storage)
guard let modulus = key.modulus, let exponent = key.exponent else {
throw CryptoKitError.incorrectParameterSize
}
return try .init(n: modulus, e: exponent)
}

public func verifySignature<S, D>(_ signature: S, for data: D, using algorithm: JSONWebSignatureAlgorithm) throws where S: DataProtocol, D: DataProtocol {
Expand Down Expand Up @@ -86,8 +89,11 @@ extension _RSA.Signing.PrivateKey: JSONWebSigningKey {
}

public static func create(storage: JSONWebValueStorage) throws -> _RSA.Signing.PrivateKey {
let der = try RSAHelper.pkcs1Representation(AnyJSONWebKey(storage: storage))
return try .init(derRepresentation: der)
let key = AnyJSONWebKey(storage: storage)
guard let modulus = key.modulus, let exponent = key.exponent, let privateExponent = key.privateExponent, let p = key.firstPrimeFactor, let q = key.secondPrimeFactor else {
throw CryptoKitError.incorrectParameterSize
}
return try .init(n: modulus, e: exponent, d: privateExponent, p: p, q: q)
}

public func signature<D>(_ data: D, using algorithm: JSONWebSignatureAlgorithm) throws -> Data where D: DataProtocol {
Expand Down Expand Up @@ -153,8 +159,11 @@ extension _RSA.Encryption.PublicKey: JSONWebEncryptingKey {
}

public static func create(storage: JSONWebValueStorage) throws -> _RSA.Encryption.PublicKey {
let der = try RSAHelper.pkcs1Representation(AnyJSONWebKey(storage: storage))
return try .init(derRepresentation: der)
let key = AnyJSONWebKey(storage: storage)
guard let modulus = key.modulus, let exponent = key.exponent else {
throw CryptoKitError.incorrectParameterSize
}
return try .init(n: modulus, e: exponent)
}

public func encrypt<D, JWA>(_ data: D, using algorithm: JWA) throws -> Data where D: DataProtocol, JWA: JSONWebAlgorithm {
Expand Down Expand Up @@ -190,8 +199,11 @@ extension _RSA.Encryption.PrivateKey: JSONWebDecryptingKey {
}

public static func create(storage: JSONWebValueStorage) throws -> _RSA.Encryption.PrivateKey {
let der = try RSAHelper.pkcs1Representation(AnyJSONWebKey(storage: storage))
return try .init(derRepresentation: der)
let key = AnyJSONWebKey(storage: storage)
guard let modulus = key.modulus, let exponent = key.exponent, let privateExponent = key.privateExponent, let p = key.firstPrimeFactor, let q = key.secondPrimeFactor else {
throw CryptoKitError.incorrectParameterSize
}
return try .init(n: modulus, e: exponent, d: privateExponent, p: p, q: q)
}

public func decrypt<D, JWA>(_ data: D, using algorithm: JWA) throws -> Data where D: DataProtocol, JWA: JSONWebAlgorithm {
Expand Down
4 changes: 2 additions & 2 deletions Sources/JWSETKit/Cryptography/Symmetric/CommonCrypto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ extension SymmetricKey {
}

static func ccPbkdf2<PD, SD, H>(
pbkdf2Password password: PD, salt: SD, iterations: Int, length: Int? = nil, hashFunction: H.Type
pbkdf2Password password: PD, salt: SD, iterations: Int, length: Int, hashFunction: H.Type
) throws -> SymmetricKey where PD: DataProtocol, SD: DataProtocol, H: HashFunction {
let hash = try CCPseudoRandomAlgorithm(hashFunction)
var derivedKeyData = Data(repeating: 0, count: length ?? hashFunction.Digest.byteCount)
var derivedKeyData = Data(repeating: 0, count: length)
let derivedCount = derivedKeyData.count

let derivationStatus: OSStatus = derivedKeyData.withUnsafeMutableBytes { derivedKeyBytes in
Expand Down
32 changes: 13 additions & 19 deletions Sources/JWSETKit/Cryptography/Symmetric/PBKDF2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@

import Foundation
import Crypto
#if canImport(CommonCrypto)
import CommonCrypto
#endif
#if canImport(CryptoSwift)
import CryptoSwift
#if canImport(_CryptoExtras)
import _CryptoExtras
#endif

extension SymmetricKey {
static let defaultPBES2IterationCount: [Int: Int] = [
128: 310_000,
192: 250_000,
256: 120_000,
128: 600_000,
192: 450_000,
256: 210_000,
]

/// Generates a symmetric key using `PBKDF2` algorithm.
Expand All @@ -33,12 +30,11 @@ extension SymmetricKey {
public static func paswordBased2DerivedSymmetricKey<PD, SD, H>(
password: PD, salt: SD, iterations: Int, length: Int? = nil, hashFunction: H.Type
) throws -> SymmetricKey where PD: DataProtocol, SD: DataProtocol, H: HashFunction {
let length = length ?? hashFunction.Digest.byteCount
#if canImport(CommonCrypto)
return try ccPbkdf2(pbkdf2Password: password, salt: salt, iterations: iterations, length: length, hashFunction: hashFunction)
#elseif canImport(CryptoSwift)
let variant = try CryptoSwift.HMAC.Variant(hashFunction)
let key = try PKCS5.PBKDF2(password: [UInt8](password), salt: [UInt8](salt), iterations: iterations, keyLength: length, variant: variant).calculate()
return .init(data: key)
#elseif canImport(_CryptoExtras)
return try KDF.Insecure.PBKDF2.deriveKey(from: password, salt: salt, using: .init(hashFunction), outputByteCount: length, unsafeUncheckedRounds: iterations)
#else
// This should never happen as CommonCrypto is available on Darwin platforms
// and CryptoSwift is used on non-Darwin platform.
Expand All @@ -47,20 +43,18 @@ extension SymmetricKey {
}
}

#if canImport(CryptoSwift)
extension CryptoSwift.HMAC.Variant {
extension KDF.Insecure.PBKDF2.HashFunction {
init<H>(_: H.Type) throws where H: HashFunction {
if H.self == Insecure.SHA1.self {
self = .sha1
self = .insecureSHA1
} else if H.self == SHA256.self {
self = .sha2(.sha256)
self = .sha256
} else if H.self == SHA384.self {
self = .sha2(.sha384)
self = .sha384
} else if H.self == SHA512.self {
self = .sha2(.sha512)
self = .sha512
} else {
throw CryptoKitError.incorrectKeySize
}
}
}
#endif

0 comments on commit 4556362

Please sign in to comment.