Skip to content

Commit 3068de5

Browse files
authored
Merge pull request #3 from codingstill/feature/hs-support
Feature/hs support
2 parents 773f5f2 + 7a8fa2d commit 3068de5

File tree

6 files changed

+445
-9
lines changed

6 files changed

+445
-9
lines changed

JwtManager/HsJwt.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Security.Cryptography;
5+
using System.Text;
6+
7+
namespace JwtManager
8+
{
9+
public class HsJwt : Jwt
10+
{
11+
public Helpers.KeySize KeySize { get; set; }
12+
public string Secret { get; set; }
13+
14+
public override string Sign(string payload)
15+
{
16+
List<string> segments = new List<string>();
17+
JwtHeader header = Header;
18+
19+
DateTime issued = DateTime.Now;
20+
DateTime expire = DateTime.Now.AddHours(10);
21+
22+
byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None));
23+
byte[] payloadBytes = Encoding.UTF8.GetBytes(payload);
24+
25+
segments.Add(Helpers.Base64Helper.UrlEncode(headerBytes));
26+
segments.Add(Helpers.Base64Helper.UrlEncode(payloadBytes));
27+
28+
string stringToSign = string.Join(".", segments.ToArray());
29+
30+
byte[] bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
31+
32+
byte[] secret = Encoding.UTF8.GetBytes(Secret);
33+
34+
HMAC alg = GetHMAC(secret);
35+
byte[] hash = alg.ComputeHash(bytesToSign);
36+
37+
segments.Add(Helpers.Base64Helper.UrlEncode(hash));
38+
39+
return string.Join(".", segments.ToArray());
40+
}
41+
42+
public override string Validate(string token)
43+
{
44+
string[] parts = token.Split('.');
45+
string header = parts[0];
46+
string payload = parts[1];
47+
string signature = parts[2];
48+
49+
string headerJson = Encoding.UTF8.GetString(Helpers.Base64Helper.UrlDecode(header));
50+
string payloadJson = Encoding.UTF8.GetString(Helpers.Base64Helper.UrlDecode(payload));
51+
52+
byte[] bytesToSign = Encoding.UTF8.GetBytes(string.Join(".", header, payload));
53+
54+
byte[] secret = Encoding.UTF8.GetBytes(Secret);
55+
56+
HMAC alg = GetHMAC(secret);
57+
byte[] hash = alg.ComputeHash(bytesToSign);
58+
59+
string computedSignature = Helpers.Base64Helper.UrlEncode(hash);
60+
61+
if(signature != computedSignature)
62+
{
63+
throw new Exception("Invalid signature.");
64+
}
65+
66+
return payloadJson;
67+
}
68+
69+
private JwtHeader Header
70+
{
71+
get
72+
{
73+
return new JwtHeader { alg = "HS" + KeySize.ToString(), typ = "JWT" };
74+
}
75+
}
76+
77+
private HMAC GetHMAC(byte[] secret)
78+
{
79+
switch(KeySize)
80+
{
81+
case Helpers.KeySize.S256:
82+
return new HMACSHA256(secret);
83+
case Helpers.KeySize.S384:
84+
return new HMACSHA384(secret);
85+
case Helpers.KeySize.S512:
86+
return new HMACSHA512(secret);
87+
default:
88+
throw new Exception("Non-valid key size.");
89+
}
90+
}
91+
}
92+
}

JwtManager/JwtManager.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="BouncyCastle.NetCore" Version="1.8.3" />
11-
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
10+
<PackageReference Include="BouncyCastle.NetCore" Version="1.8.5" />
11+
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
1212
</ItemGroup>
1313

1414
</Project>

JwtManager/RsJwt.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public override string Validate(string token)
8282
byte[] tmp = Helpers.Base64Helper.UrlDecode(signature);
8383
if (!rsaDeformatter.VerifySignature(hash, tmp))
8484
{
85-
throw new Exception("Invalid signature");
85+
throw new Exception("Invalid signature.");
8686
}
8787

8888
return payloadJson;

0 commit comments

Comments
 (0)