Skip to content

Commit 395408c

Browse files
committed
wip: rsa
1 parent 45e5d4a commit 395408c

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

Sources/JWA/RSA/RSA.swift

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#if os(macOS)
2+
3+
import Foundation
4+
import CommonCrypto
5+
import Security
6+
7+
@available(OSX 10.12, *)
8+
public enum RSAHash {
9+
case sha256
10+
case sha384
11+
case sha512
12+
13+
var algorithm: SecKeyAlgorithm {
14+
switch self {
15+
case .sha256:
16+
return SecKeyAlgorithm.rsaSignatureDigestPKCS1v15SHA256
17+
case .sha384:
18+
return SecKeyAlgorithm.rsaSignatureDigestPKCS1v15SHA384
19+
case .sha512:
20+
return SecKeyAlgorithm.rsaSignatureDigestPKCS1v15SHA512
21+
}
22+
}
23+
}
24+
25+
26+
@available(OSX 10.12, *)
27+
final public class RSAPublicKey: Algorithm, VerifyAlgorithm {
28+
let hash: RSAHash
29+
let key: SecKey
30+
31+
public init(key: SecKey, hash: RSAHash) {
32+
self.hash = hash
33+
self.key = key
34+
}
35+
36+
public var name: String {
37+
switch hash {
38+
case .sha256:
39+
return "RS256"
40+
case .sha384:
41+
return "RS384"
42+
case .sha512:
43+
return "RS512"
44+
}
45+
}
46+
47+
public func verify(_ message: Data, signature: Data) -> Bool {
48+
var error: Unmanaged<CFError>?
49+
let result = SecKeyVerifySignature(key, hash.algorithm, message as NSData, signature as NSData, &error)
50+
print(error)
51+
return result
52+
}
53+
}
54+
55+
56+
//@available(OSX 10.12, *)
57+
//final public class RSAPrivateKey: Algorithm {//, SignAlgorithm {
58+
// let hash: RSAHash
59+
// let key: SecKey
60+
//
61+
// public init(key: SecKey, hash: RSAHash) {
62+
// // TODO is sec key
63+
// self.hash = hash
64+
// self.key = key
65+
// }
66+
//
67+
// public var name: String {
68+
// switch hash {
69+
// case .sha256:
70+
// return "RS256"
71+
// case .sha384:
72+
// return "RS384"
73+
// case .sha512:
74+
// return "RS512"
75+
// }
76+
// }
77+
//
78+
// public func verify(_ message: Data, signature: Data) -> Bool {
79+
// let alg = SecKeyAlgorithm.rsaSignatureDigestPKCS1v15SHA256
80+
// return SecKeyVerifySignature(key, alg, message as NSData, signature as NSData, nil)
81+
// }
82+
//
83+
// public func sign(_ message: Data) -> Data {
84+
// let alg = SecKeyAlgorithm.rsaSignatureDigestPKCS1v15SHA256
85+
//
86+
// var error: Unmanaged<CFError>?
87+
// guard let x = SecKeyCreateSignature(key, alg, message as NSData, &error) else {
88+
// fatalError("\(error?.takeRetainedValue())")
89+
// }
90+
//
91+
// return x as NSData as Data
92+
//// sign(<#T##message: Data##Data#>)
93+
// }
94+
//}
95+
96+
#endif

Tests/JWATests/RSATests.swift

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import Foundation
2+
import XCTest
3+
import JWA
4+
5+
6+
@available(OSX 10.12, *)
7+
class RSAPublicKeyAlgorithmTests: XCTestCase {
8+
let publicKeyData = Data(base64Encoded: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB")!
9+
let privateKeyData = Data(base64Encoded: "MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQABAoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5CpuGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0KSu5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aPFaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==")!
10+
var publicKey: SecKey {
11+
let attributes: [String: Any] = [
12+
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
13+
kSecAttrKeySizeInBits as String: 2048,
14+
kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
15+
]
16+
17+
var error: Unmanaged<CFError>?
18+
guard let key = SecKeyCreateWithData(publicKeyData as NSData, attributes as NSDictionary, &error) else {
19+
fatalError("\(error!.takeRetainedValue())")
20+
}
21+
22+
return key
23+
}
24+
var privateKey: SecKey {
25+
let attributes: [String: Any] = [
26+
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
27+
kSecAttrKeySizeInBits as String: 2048,
28+
kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
29+
]
30+
31+
var error: Unmanaged<CFError>?
32+
guard let key = SecKeyCreateWithData(privateKeyData as NSData, attributes as NSDictionary, &error) else {
33+
fatalError("\(error!.takeRetainedValue())")
34+
}
35+
36+
return key
37+
}
38+
39+
let message = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9".data(using: .utf8)!
40+
let sha256Signature = Data(base64Encoded: "EkN+DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8jO19W/A4K8ZPJijNLis4EZsHeY559a4DFOd50/OqgHGuERTqYZyuhtF39yxJPAjUESwxk2J5k/4zM3O+vtd1Ghyo4IbqKKSy6J9mTniYJPenn5+HIirE=")!
41+
let sha384Signature = Data(base64Encoded: "rQ706A2kJ7KjPURXyXK/dZ9Qdm+7ZlaQ1Qt8s43VIX21Wck+p8vuSOKuGltKr9NL")!
42+
let sha512Signature = Data(base64Encoded: "G7pYfHMO7box9Tq7C2ylieCd5OiU7kVeYUCAc5l1mtqvoGnux8AWR7sXPcsX9V0ir0mhgHG3SMXC7df3qCnGMg==")!
43+
44+
// MARK: Name
45+
46+
func testSHA256Name() {
47+
let algorithm = RSAPublicKey(key: publicKey, hash: .sha256)
48+
XCTAssertEqual(algorithm.name, "RS256")
49+
}
50+
51+
func testSHA384Name() {
52+
let algorithm = RSAPublicKey(key: publicKey, hash: .sha384)
53+
XCTAssertEqual(algorithm.name, "RS384")
54+
}
55+
56+
func testSHA512Name() {
57+
let algorithm = RSAPublicKey(key: publicKey, hash: .sha512)
58+
XCTAssertEqual(algorithm.name, "RS512")
59+
}
60+
61+
// MARK: Signing
62+
//
63+
// func testSHA256Sign() {
64+
// let algorithm = HMACAlgorithm(key: key, hash: .sha256)
65+
// XCTAssertEqual(algorithm.sign(message), sha256Signature)
66+
// }
67+
//
68+
// func testSHA384Sign() {
69+
// let algorithm = HMACAlgorithm(key: key, hash: .sha384)
70+
// XCTAssertEqual(algorithm.sign(message), sha384Signature)
71+
// }
72+
//
73+
// func testSHA512Sign() {
74+
// let algorithm = HMACAlgorithm(key: key, hash: .sha512)
75+
// XCTAssertEqual(algorithm.sign(message), sha512Signature)
76+
// }
77+
//
78+
// MARK: Verify
79+
80+
func testSHA256Verify() {
81+
let algorithm = RSAPublicKey(key: publicKey, hash: .sha256)
82+
XCTAssertTrue(algorithm.verify(message, signature: sha256Signature))
83+
84+
// let a = RSAPrivateKey(key: privateKey, hash: .sha256)
85+
// XCTAssertEqual(a.sign(message), sha256Signature)
86+
}
87+
88+
func testSHA384Verify() {
89+
let algorithm = RSAPublicKey(key: publicKey, hash: .sha384)
90+
XCTAssertTrue(algorithm.verify(message, signature: sha384Signature))
91+
}
92+
93+
func testSHA512Verify() {
94+
let algorithm = RSAPublicKey(key: publicKey, hash: .sha512)
95+
XCTAssertTrue(algorithm.verify(message, signature: sha512Signature))
96+
}
97+
}

0 commit comments

Comments
 (0)