Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 245: rsa-oaep-384|512 #254

Merged
merged 6 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ JWE JSON Serialization cross-tested with [JWCrypto](https://github.com/latchset/
Library is fully FIPS compliant since v2.1

## Which version?
- v5.1 support for experimental algorithms RSA-OAEP-384, RSA-OAEP-512

- v5.0 brings Linux, OSX and FreeBSD compatibility for [ECDH encryption](#ecdh-es-and-ecdh-es-with-aes-key-wrap-key-management-family-of-algorithms) as long as managed `ECDsa` keys support. Fixes cross compatibility issues with encryption over NIST P-384, P-521 curves. And introduces new [security fixes and controls](#customizing-compression).

- v4.1 added additional capabilities to manage runtime avaliable alg suite, see [Customizing library for security](#customizing-library-for-security). And also introduced default max limits for `PBKDF2` (`PBES2-*`) max iterations according to [OWASP PBKDF2 Recomendations](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2).
Expand Down Expand Up @@ -78,7 +80,7 @@ AES Key Wrap implementation ideas and test data from http://www.cryptofreak.org/
- NONE (unprotected) plain text algorithm without integrity protection

**Encryption**
- RSAES OAEP 256 (using SHA-256 and MGF1 with SHA-256) encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM
- RSAES OAEP 256, 384, 512 (using SHA-256, 384, 512 and MGF1 with SHA-256, 384, 512) encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM
- RSAES OAEP (using SHA-1 and MGF1 with SHA-1) encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM
- RSAES-PKCS1-V1_5 encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM
- Direct symmetric key encryption with pre-shared key A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM and A256GCM
Expand All @@ -101,7 +103,7 @@ AES Key Wrap implementation ideas and test data from http://www.cryptofreak.org/
- NONE (unprotected) plain text algorithm without integrity protection

**Encryption**
- RSAES OAEP 256 (using SHA-256 and MGF1 with SHA-256) encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM
- RSAES OAEP 256, 384, 512 (using SHA-256, 384, 512 and MGF1 with SHA-256, 384, 512) encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM
- RSAES OAEP (using SHA-1 and MGF1 with SHA-1) encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM
- RSAES-PKCS1-V1_5 encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM
- Direct symmetric key encryption with pre-shared key A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM and A256GCM
Expand Down Expand Up @@ -302,7 +304,7 @@ Accepts `CngKey`, `ECDsa` and `Jwk` types of keys (see above).

**NET40-NET45**:

RSA-OAEP-256, RSA-OAEP and RSA1_5 key management requires `RSACryptoServiceProvider` (usually public) key of corresponding length.
RSA-OAEP-256, RSA-OAEP-384, RSA-OAEP-512, RSA-OAEP and RSA1_5 key management requires `RSACryptoServiceProvider` (usually public) key of corresponding length.

```C#
var payload = new Dictionary<string, object>()
Expand All @@ -317,7 +319,7 @@ string token = Jose.JWT.Encode(payload, publicKey, JweAlgorithm.RSA_OAEP, JweEnc
```

**NETCORE:**
RSA-OAEP-256, RSA-OAEP and RSA1_5 key management requires `RSA` (usually public) or `Jwk` key of type `RSA` of corresponding length.
RSA-OAEP-256, RSA-OAEP-384, RSA-OAEP-512, RSA-OAEP and RSA1_5 key management requires `RSA` (usually public) or `Jwk` key of type `RSA` of corresponding length.

``` cs
var payload = new Dictionary<string, object>()
Expand Down Expand Up @@ -587,7 +589,7 @@ string json = Jose.JWT.Decode(token, secretKey);
string json = Jose.JWT.Decrypt(token, secretKey);
```

**RS256, RS384, RS512**, **PS256, PS384, PS512** signatures and **RSA-OAEP-256**, **RSA-OAEP, RSA1_5** key management algorithms expects
**RS256, RS384, RS512**, **PS256, PS384, PS512** signatures and **RSA-OAEP-256**, **RSA-OAEP-384**, **RSA-OAEP-512**, **RSA-OAEP, RSA1_5** key management algorithms expects

**NET40-NET45**: `RSACryptoServiceProvider` as a key, public/private is asymmetric to encoding:

Expand Down
94 changes: 94 additions & 0 deletions UnitTests/TestSuite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,51 @@ public void Decrypt_RSA_OAEP_256_A256CBC_HS512()
Assert.Equal(@"{""exp"":1392553211,""sub"":""alice"",""nbf"":1392552611,""aud"":[""https:\/\/app-one.com"",""https:\/\/app-two.com""],""iss"":""https:\/\/openid.net"",""jti"":""586dd129-a29f-49c8-9de7-454af1155e27"",""iat"":1392552611}", json);
}

[Fact]
public void Decrypt_RSA_OAEP_256_A128GCM()
{
//given
const string token = "eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.Ki1uPWs34nXxE2nGmie94nGkcl1KbJcutGIRL2x7025JXITQ905nGlMqPf4YjgzvJxj51oc0EARPfC6IrFVlefuJzeKbJgZNj0IBkIKL1UbxkP0PrCovuXOnQhfYbcbppC0uNA6SDdGUiCJZH9DNnEBjQcbUWmDAdLSmI0ZkBhYK7fsla7dITP6rcAPM8wQcN6JqcVFZ-s_-uP8B6o2ywkawdtTacsQq9UxJvJ5bKfXJSNT-0xZY5kevgUo7rbJIpzv6BpFsA4EduOVMGu9Y7Xu_4seNIHZQA4NEqTxtbwjuq1lUdkm6Bnkr7GSXJ8tRjoFRf6OD2aX-snFx6Zg-MA.ez2XiQxsD1dvkehk._UCAGhvkeUWHKNa5lHQZvPpvWyH7j4E6wPJFLeNIFe53WCWVBVqFPoBRa5SANLak2COOgF__KBezLp935hROEvmtgFqJ5adl9uF501fCN0Cq-53bZP5MjKP237fOcZYQrGcei2GRRG-vOMt--owVX0Wjyy4Jy0oLqf9-hHoImtyLTpM89nN1s3jKcpsMntIfiqespShHLehZ0zW4v9pzT0ScHmSdjSqsisqcA0Za71GzPRoNIq5BzCvIf0TR6Q.hm0FdUsB0iHd1yrJW4Omzg";

//when
string json = Jose.JWT.Decode(token, testSuiteUtils.PrivKey());

//then
Console.Out.WriteLine("json = {0}", json);

Assert.Equal(@"{""sub"":""alice"",""aud"":[""https://app-one.com"",""https://app-two.com""],""nbf"":1730312729,""iss"":""https://openid.net"",""exp"":1730313329,""iat"":1730312729,""jti"":""d8915fdb-8985-4c86-ae8d-28567016f623""}", json);
}

[Fact]
public void Decrypt_RSA_OAEP_384_A192GCM()
{
//given
const string token = "eyJlbmMiOiJBMTkyR0NNIiwiYWxnIjoiUlNBLU9BRVAtMzg0In0.pHwaRvG-WVUQtofFUwjedVIY_MxZs8V3ulf-46pFSAKqyERjJF0Za-LoDqN_EvMMwJp4TJ2JgEFHk9vLoThh-7EtJ3noaLaDxTXbt38slZ6xw1J-dziSUKXaiJstUiGLuJAK5liKwFWdqNtolBG0plEc2vvuROu7xUNoFuwb286992sKOAQb_1CFomDk5QuaiTN8pDwtQDLt8UsU5Gurml1U9bdU08FnH0PYIZlyVxKDL7a_fAfG-4o9_S__p8xLpYfp0aKX4MMbHSZcnMgqiwbfx_PiWQLhTYWeqf8XNNEYnGdv_QHK11FAd2NnT_RS028WJkf9W8veJTc-UUujjg.yej5UbPyU3A9gQD2.euXP6xG2-cLGJ0rTTjhwbeUX-qUKgT0Rr5JmtwDtGpZG8LyUpTpYhhLLcDTMtiUd0l0GeJPRzeApt5XTy-2RgpS-vcTn0b4t2xH27GPtN5Jvvsc-0rJlSbmptIE3QImrbckEXnwNCbz0qt95wPFSde04UzRWsna-LaSQ6se_pXbfga2kn5TiZ6ZKWh6fcfV6WIY3DtcWY1GCwdX2VW1vrqp-EQbWrOKqZp8Zx6BLwo521SPFg36EnJZWopoQBA.ZAC9GsPtN4P_ZhEKU1Hnpg";

//when
string json = Jose.JWT.Decode(token, testSuiteUtils.PrivKey());

//then
Console.Out.WriteLine("json = {0}", json);

Assert.Equal(@"{""sub"":""alice"",""aud"":[""https://app-one.com"",""https://app-two.com""],""nbf"":1729866729,""iss"":""https://openid.net"",""exp"":1729867329,""iat"":1729866729,""jti"":""da2aa440-2923-4501-b169-04fe0904da4d""}", json);
}

[Fact]
public void Decrypt_RSA_OAEP_512_A256GCM()
{
//given
const string token = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtNTEyIn0.Xti41IW1gNT9RqV2Eah4v8ylTP_E1DOjniWw9EJbEHTWzAjXeQ7sWdHLgH_h7G6xNhppLziGbsSZeqBcB_r-jkRXkSpP-kUyKp8QddvXCgUHHgme39LnnNjZXQ6KHBFiM0F0zQp3DJhxBe0lFEezrW3oSjusX43ybsTx3OqKWpp1TwhLyiGtjrKP82b2KcPS8XHT5mOP-_-KFKqOtut3m4jpLO6xYTClP-HZFtTHTz-CrK1y5XisDez-hk9LwzwJu0G-MFL5mNtWL24yeskbD2JWXzOHpkywiZ-pUU_BkfGqCHJnNGlbbX19xEHpd4a4XkPI_IatFX7QNCZOfRoiSw.mftbPhWtNUuxaRO_.GQPlZZruXeXEWeYu6QtCbu0i2bXBWThic-5VjVlRa2hu_ZJm1X4yUmmLdIsc8AE0F28dxbgvAI6HxTwVJkihPT_n5EF8zMdUPsTOMmxQOqfyRWgNX1WOvFgtsf8D1AlQ0Ukf0Pyt57nb-0ha6x5Bj9jMUmGQNfL98bDzNYrR-Y-cHIRfXzbyXw3u5f4qdczmdsNgWJ7ZQSm-4Rc8QSCP70bnISRPehhIOGYrKJenL9GaIUZa0lRrNv6YS17mhQ.6R_c3mLxSQ524Uk8usfNPg";

//when
string json = Jose.JWT.Decode(token, testSuiteUtils.PrivKey());

//then
Console.Out.WriteLine("json = {0}", json);

Assert.Equal(@"{""sub"":""alice"",""aud"":[""https://app-one.com"",""https://app-two.com""],""nbf"":1729866729,""iss"":""https://openid.net"",""exp"":1729867329,""iat"":1729866729,""jti"":""b02ef943-92d6-4bf4-b7ac-18d2e122efa5""}", json);
}

[Fact]
public void Encrypt_RSA_OAEP_256_A128GCM()
{
Expand Down Expand Up @@ -1007,6 +1052,55 @@ public void Encrypt_RSA_OAEP_256_A128GCM_JsonWebKey()
Assert.Equal(json, Jose.JWT.Decode(token, testSuiteUtils.PrivKey()));
}

[Fact]
public void Encrypt_RSA_OAEP_384_A192GCM()
{
//given
const string json = @"{""hello"": ""world""}";

//when
string token = Jose.JWT.Encode(json, testSuiteUtils.PubKey(), JweAlgorithm.RSA_OAEP_384, JweEncryption.A192GCM);

//then
Console.Out.WriteLine("RSA_OAEP_384_A192GCM={0}", token);

string[] parts = token.Split('.');

Assert.Equal(5, parts.Length); //Make sure 5 parts
Assert.Equal("eyJhbGciOiJSU0EtT0FFUC0zODQiLCJlbmMiOiJBMTkyR0NNIn0", parts[0]); //Header is non-encrypted and static text
Assert.Equal(342, parts[1].Length); //CEK size
Assert.Equal(16, parts[2].Length); //IV size
Assert.Equal(24, parts[3].Length); //cipher text size
Assert.Equal(22, parts[4].Length); //auth tag size

Assert.Equal(json, Jose.JWT.Decode(token, testSuiteUtils.PrivKey()));
}

[Fact]
public void Encrypt_RSA_OAEP_512_A256GCM()
{
//given
const string json = @"{""hello"": ""world""}";

//when
Jwk publicKey = new Jwk("AQAB", "qFZv0pea_jn5Mo4qEUmStuhlulso8n1inXbEotd_zTrQp9K0RK0hf7t0K4BjKVhaiqIam4tVVQvkmYeBeYr1MmnO_0N97dMBz_7fmvyv0hgHaBdQ5mR5u3LTlHo8tjRE7-GzZmGs6jMcyj7HbXobDPQJZpqNy6JjliDVXxW8nWJDetxGBlqmTj1E1fr2RCsZLreDOPSDIedG1upz9RraShsIDzeefOcKibcAaKeeVI3rkAU8_mOauLSXv37hlk0h6sStJb3qZQXyOUkVkjXIkhvNu_ve0v7LiLT4G_OxYGzpOQcCnimKdojzNP6GtVDaMPh-QkSJE32UCos9R3wI2Q");
string token = Jose.JWT.Encode(json, publicKey, JweAlgorithm.RSA_OAEP_512, JweEncryption.A256GCM);

//then
Console.Out.WriteLine("RSA_OAEP_512_A256GCM={0}", token);

string[] parts = token.Split('.');

Assert.Equal(5, parts.Length); //Make sure 5 parts
Assert.Equal("eyJhbGciOiJSU0EtT0FFUC01MTIiLCJlbmMiOiJBMjU2R0NNIn0", parts[0]); //Header is non-encrypted and static text
Assert.Equal(342, parts[1].Length); //CEK size
Assert.Equal(16, parts[2].Length); //IV size
Assert.Equal(24, parts[3].Length); //cipher text size
Assert.Equal(22, parts[4].Length); //auth tag size

Assert.Equal(json, Jose.JWT.Decode(token, testSuiteUtils.PrivKey()));
}

[Fact]
public void Encrypt_RSA_OAEP_256_A192GCM()
{
Expand Down
93 changes: 93 additions & 0 deletions UnitTestsNet40/TestSuite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,51 @@ public void Decrypt_RSA_OAEP_256_A256CBC_HS512()
Assert.That(json, Is.EqualTo(@"{""exp"":1392553211,""sub"":""alice"",""nbf"":1392552611,""aud"":[""https:\/\/app-one.com"",""https:\/\/app-two.com""],""iss"":""https:\/\/openid.net"",""jti"":""586dd129-a29f-49c8-9de7-454af1155e27"",""iat"":1392552611}"));
}

[Test]
public void Decrypt_RSA_OAEP_256_A128GCM()
{
//given
const string token = "eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.Ki1uPWs34nXxE2nGmie94nGkcl1KbJcutGIRL2x7025JXITQ905nGlMqPf4YjgzvJxj51oc0EARPfC6IrFVlefuJzeKbJgZNj0IBkIKL1UbxkP0PrCovuXOnQhfYbcbppC0uNA6SDdGUiCJZH9DNnEBjQcbUWmDAdLSmI0ZkBhYK7fsla7dITP6rcAPM8wQcN6JqcVFZ-s_-uP8B6o2ywkawdtTacsQq9UxJvJ5bKfXJSNT-0xZY5kevgUo7rbJIpzv6BpFsA4EduOVMGu9Y7Xu_4seNIHZQA4NEqTxtbwjuq1lUdkm6Bnkr7GSXJ8tRjoFRf6OD2aX-snFx6Zg-MA.ez2XiQxsD1dvkehk._UCAGhvkeUWHKNa5lHQZvPpvWyH7j4E6wPJFLeNIFe53WCWVBVqFPoBRa5SANLak2COOgF__KBezLp935hROEvmtgFqJ5adl9uF501fCN0Cq-53bZP5MjKP237fOcZYQrGcei2GRRG-vOMt--owVX0Wjyy4Jy0oLqf9-hHoImtyLTpM89nN1s3jKcpsMntIfiqespShHLehZ0zW4v9pzT0ScHmSdjSqsisqcA0Za71GzPRoNIq5BzCvIf0TR6Q.hm0FdUsB0iHd1yrJW4Omzg";

//when
string json = Jose.JWT.Decode(token, RsaKey.New(PrivKey().ExportParameters(true)));

//then
Console.Out.WriteLine("json = {0}", json);

Assert.That(json, Is.EqualTo(@"{""sub"":""alice"",""aud"":[""https://app-one.com"",""https://app-two.com""],""nbf"":1730312729,""iss"":""https://openid.net"",""exp"":1730313329,""iat"":1730312729,""jti"":""d8915fdb-8985-4c86-ae8d-28567016f623""}"));
}

[Test]
public void Decrypt_RSA_OAEP_384_A192GCM()
{
//given
const string token = "eyJlbmMiOiJBMTkyR0NNIiwiYWxnIjoiUlNBLU9BRVAtMzg0In0.pHwaRvG-WVUQtofFUwjedVIY_MxZs8V3ulf-46pFSAKqyERjJF0Za-LoDqN_EvMMwJp4TJ2JgEFHk9vLoThh-7EtJ3noaLaDxTXbt38slZ6xw1J-dziSUKXaiJstUiGLuJAK5liKwFWdqNtolBG0plEc2vvuROu7xUNoFuwb286992sKOAQb_1CFomDk5QuaiTN8pDwtQDLt8UsU5Gurml1U9bdU08FnH0PYIZlyVxKDL7a_fAfG-4o9_S__p8xLpYfp0aKX4MMbHSZcnMgqiwbfx_PiWQLhTYWeqf8XNNEYnGdv_QHK11FAd2NnT_RS028WJkf9W8veJTc-UUujjg.yej5UbPyU3A9gQD2.euXP6xG2-cLGJ0rTTjhwbeUX-qUKgT0Rr5JmtwDtGpZG8LyUpTpYhhLLcDTMtiUd0l0GeJPRzeApt5XTy-2RgpS-vcTn0b4t2xH27GPtN5Jvvsc-0rJlSbmptIE3QImrbckEXnwNCbz0qt95wPFSde04UzRWsna-LaSQ6se_pXbfga2kn5TiZ6ZKWh6fcfV6WIY3DtcWY1GCwdX2VW1vrqp-EQbWrOKqZp8Zx6BLwo521SPFg36EnJZWopoQBA.ZAC9GsPtN4P_ZhEKU1Hnpg";

//when
string json = Jose.JWT.Decode(token, PrivKey());

//then
Console.Out.WriteLine("json = {0}", json);

Assert. That(json, Is.EqualTo(@"{""sub"":""alice"",""aud"":[""https://app-one.com"",""https://app-two.com""],""nbf"":1729866729,""iss"":""https://openid.net"",""exp"":1729867329,""iat"":1729866729,""jti"":""da2aa440-2923-4501-b169-04fe0904da4d""}"));
}

[Test]
public void Decrypt_RSA_OAEP_512_A256GCM()
{
//given
const string token = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtNTEyIn0.Xti41IW1gNT9RqV2Eah4v8ylTP_E1DOjniWw9EJbEHTWzAjXeQ7sWdHLgH_h7G6xNhppLziGbsSZeqBcB_r-jkRXkSpP-kUyKp8QddvXCgUHHgme39LnnNjZXQ6KHBFiM0F0zQp3DJhxBe0lFEezrW3oSjusX43ybsTx3OqKWpp1TwhLyiGtjrKP82b2KcPS8XHT5mOP-_-KFKqOtut3m4jpLO6xYTClP-HZFtTHTz-CrK1y5XisDez-hk9LwzwJu0G-MFL5mNtWL24yeskbD2JWXzOHpkywiZ-pUU_BkfGqCHJnNGlbbX19xEHpd4a4XkPI_IatFX7QNCZOfRoiSw.mftbPhWtNUuxaRO_.GQPlZZruXeXEWeYu6QtCbu0i2bXBWThic-5VjVlRa2hu_ZJm1X4yUmmLdIsc8AE0F28dxbgvAI6HxTwVJkihPT_n5EF8zMdUPsTOMmxQOqfyRWgNX1WOvFgtsf8D1AlQ0Ukf0Pyt57nb-0ha6x5Bj9jMUmGQNfL98bDzNYrR-Y-cHIRfXzbyXw3u5f4qdczmdsNgWJ7ZQSm-4Rc8QSCP70bnISRPehhIOGYrKJenL9GaIUZa0lRrNv6YS17mhQ.6R_c3mLxSQ524Uk8usfNPg";

//when
string json = Jose.JWT.Decode(token, PrivKey());

//then
Console.Out.WriteLine("json = {0}", json);

Assert.That(json, Is.EqualTo(@"{""sub"":""alice"",""aud"":[""https://app-one.com"",""https://app-two.com""],""nbf"":1729866729,""iss"":""https://openid.net"",""exp"":1729867329,""iat"":1729866729,""jti"":""b02ef943-92d6-4bf4-b7ac-18d2e122efa5""}"));
}

[Test]
public void Encrypt_RSA_OAEP_256_A128GCM()
{
Expand Down Expand Up @@ -803,6 +848,54 @@ public void Encrypt_RSA_OAEP_256_A256GCM()
Assert.That(Jose.JWT.Decode(token, RsaKey.New(PrivKey().ExportParameters(true))), Is.EqualTo(json), "Make sure we are consistent with ourselfs");
}

[Test]
public void Encrypt_RSA_OAEP_384_A192GCM()
{
//given
const string json = @"{""hello"": ""world""}";

//when
string token = Jose.JWT.Encode(json, RsaKey.New(PubKey().ExportParameters(false)), JweAlgorithm.RSA_OAEP_384, JweEncryption.A192GCM);

//then
Console.Out.WriteLine("RSA_OAEP_384_A192GCM={0}", token);

string[] parts = token.Split('.');

Assert.That(parts.Length, Is.EqualTo(5)); //Make sure 5 parts
Assert.That(parts[0], Is.EqualTo("eyJhbGciOiJSU0EtT0FFUC0zODQiLCJlbmMiOiJBMTkyR0NNIn0")); //Header is non-encrypted and static text
Assert.That(parts[1].Length, Is.EqualTo(342)); //CEK size
Assert.That(parts[2].Length, Is.EqualTo(16)); //IV size
Assert.That(parts[3].Length, Is.EqualTo(24)); //cipher text size
Assert.That(parts[4].Length, Is.EqualTo(22)); //auth tag size

Assert.That(Jose.JWT.Decode(token, RsaKey.New(PrivKey().ExportParameters(true))), Is.EqualTo(json));
}

[Test]
public void Encrypt_RSA_OAEP_512_A256GCM()
{
//given
const string json = @"{""hello"": ""world""}";

//when
string token = Jose.JWT.Encode(json, RsaKey.New(PubKey().ExportParameters(false)), JweAlgorithm.RSA_OAEP_512, JweEncryption.A256GCM);

//then
Console.Out.WriteLine("RSA_OAEP_512_A256GCM={0}", token);

string[] parts = token.Split('.');

Assert.That(parts.Length, Is.EqualTo(5)); //Make sure 5 parts
Assert.That(parts[0], Is.EqualTo("eyJhbGciOiJSU0EtT0FFUC01MTIiLCJlbmMiOiJBMjU2R0NNIn0")); //Header is non-encrypted and static text
Assert.That(parts[1].Length, Is.EqualTo(342)); //CEK size
Assert.That(parts[2].Length, Is.EqualTo(16)); //IV size
Assert.That(parts[3].Length, Is.EqualTo(24)); //cipher text size
Assert.That(parts[4].Length, Is.EqualTo(22)); //auth tag size

Assert.That(Jose.JWT.Decode(token, RsaKey.New(PrivKey().ExportParameters(true))), Is.EqualTo(json));
}

[Test]
public void Decrypt_RSA_1_5_A128CBC_HS256()
{
Expand Down
Loading
Loading