Skip to content

Commit 963ae96

Browse files
committedMay 29, 2018
Sub-packages for algorithms
0 parents  commit 963ae96

11 files changed

+416
-0
lines changed
 

‎.github/CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Contributing
2+
3+
This repository is a sub repository of [the JWT Framework](https://github.com/web-token/jwt-framework) project and is READ ONLY.
4+
Please do not submit any Pull Requests here. It will be automatically closed.

‎.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Please do not submit any Pull Requests here. It will be automatically closed.
2+
3+
You should submit it here: https://github.com/web-token/jwt-framework/pulls

‎A128GCM.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* The MIT License (MIT)
7+
*
8+
* Copyright (c) 2014-2018 Spomky-Labs
9+
*
10+
* This software may be modified and distributed under the terms
11+
* of the MIT license. See the LICENSE file for details.
12+
*/
13+
14+
namespace Jose\Component\Encryption\Algorithm\ContentEncryption;
15+
16+
final class A128GCM extends AESGCM
17+
{
18+
/**
19+
* {@inheritdoc}
20+
*/
21+
public function getCEKSize(): int
22+
{
23+
return 128;
24+
}
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
protected function getMode(): string
30+
{
31+
return 'aes-128-gcm';
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function name(): string
38+
{
39+
return 'A128GCM';
40+
}
41+
}

‎A192GCM.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* The MIT License (MIT)
7+
*
8+
* Copyright (c) 2014-2018 Spomky-Labs
9+
*
10+
* This software may be modified and distributed under the terms
11+
* of the MIT license. See the LICENSE file for details.
12+
*/
13+
14+
namespace Jose\Component\Encryption\Algorithm\ContentEncryption;
15+
16+
final class A192GCM extends AESGCM
17+
{
18+
/**
19+
* {@inheritdoc}
20+
*/
21+
public function getCEKSize(): int
22+
{
23+
return 192;
24+
}
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
protected function getMode(): string
30+
{
31+
return 'aes-192-gcm';
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function name(): string
38+
{
39+
return 'A192GCM';
40+
}
41+
}

‎A256GCM.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* The MIT License (MIT)
7+
*
8+
* Copyright (c) 2014-2018 Spomky-Labs
9+
*
10+
* This software may be modified and distributed under the terms
11+
* of the MIT license. See the LICENSE file for details.
12+
*/
13+
14+
namespace Jose\Component\Encryption\Algorithm\ContentEncryption;
15+
16+
final class A256GCM extends AESGCM
17+
{
18+
/**
19+
* {@inheritdoc}
20+
*/
21+
public function getCEKSize(): int
22+
{
23+
return 256;
24+
}
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
protected function getMode(): string
30+
{
31+
return 'aes-256-gcm';
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function name(): string
38+
{
39+
return 'A256GCM';
40+
}
41+
}

‎AESGCM.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* The MIT License (MIT)
7+
*
8+
* Copyright (c) 2014-2018 Spomky-Labs
9+
*
10+
* This software may be modified and distributed under the terms
11+
* of the MIT license. See the LICENSE file for details.
12+
*/
13+
14+
namespace Jose\Component\Encryption\Algorithm\ContentEncryption;
15+
16+
use Jose\Component\Encryption\Algorithm\ContentEncryptionAlgorithm;
17+
18+
abstract class AESGCM implements ContentEncryptionAlgorithm
19+
{
20+
/**
21+
* {@inheritdoc}
22+
*/
23+
public function allowedKeyTypes(): array
24+
{
25+
return []; //Irrelevant
26+
}
27+
28+
/**
29+
* {@inheritdoc}
30+
*/
31+
public function encryptContent(string $data, string $cek, string $iv, ?string $aad, string $encoded_protected_header, ?string &$tag = null): string
32+
{
33+
$calculated_aad = $encoded_protected_header;
34+
if (null !== $aad) {
35+
$calculated_aad .= '.'.$aad;
36+
}
37+
38+
$C = openssl_encrypt($data, $this->getMode(), $cek, OPENSSL_RAW_DATA, $iv, $tag, $calculated_aad);
39+
if (false === $C) {
40+
throw new \InvalidArgumentException('Unable to encrypt the data.');
41+
}
42+
43+
return $C;
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*/
49+
public function decryptContent(string $data, string $cek, string $iv, ?string $aad, string $encoded_protected_header, string $tag): string
50+
{
51+
$calculated_aad = $encoded_protected_header;
52+
if (null !== $aad) {
53+
$calculated_aad .= '.'.$aad;
54+
}
55+
56+
$P = openssl_decrypt($data, $this->getMode(), $cek, OPENSSL_RAW_DATA, $iv, $tag, $calculated_aad);
57+
if (false === $P) {
58+
throw new \InvalidArgumentException('Unable to decrypt or to verify the tag.');
59+
}
60+
61+
return $P;
62+
}
63+
64+
/**
65+
* {@inheritdoc}
66+
*/
67+
public function getIVSize(): int
68+
{
69+
return 96;
70+
}
71+
72+
/**
73+
* @return string
74+
*/
75+
abstract protected function getMode(): string;
76+
}

‎LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014-2018 Spomky-Labs
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
AES GCM Based Content Encryption Algorithms For JWT-Framework
2+
=============================================================
3+
4+
This repository is a sub repository of [the JWT Framework](https://github.com/web-token/jwt-framework) project and is READ ONLY.
5+
6+
**Please do not submit any Pull Request here.**
7+
You should go to [the main repository](https://github.com/web-token/jwt-framework) instead.
8+
9+
# Documentation
10+
11+
The official documentation is available as https://web-token.spomky-labs.com/
12+
13+
# Licence
14+
15+
This software is release under [MIT licence](LICENSE).

‎Tests/AESGCMContentEncryptionTest.php

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* The MIT License (MIT)
7+
*
8+
* Copyright (c) 2014-2018 Spomky-Labs
9+
*
10+
* This software may be modified and distributed under the terms
11+
* of the MIT license. See the LICENSE file for details.
12+
*/
13+
14+
namespace Jose\Component\Encryption\Algorithm\ContentEncryption\Tests;
15+
16+
use Base64Url\Base64Url;
17+
use Jose\Component\Encryption\Algorithm\ContentEncryption\A128GCM;
18+
use Jose\Component\Encryption\Algorithm\ContentEncryption\A192GCM;
19+
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256GCM;
20+
use PHPUnit\Framework\TestCase;
21+
22+
/**
23+
* @group Unit
24+
*/
25+
class AESGCMContentEncryptionTest extends TestCase
26+
{
27+
public function testA128GCMEncryptAndDecrypt()
28+
{
29+
$header = Base64Url::encode(json_encode(['alg' => 'ECDH-ES', 'enc' => 'A128GCM']));
30+
$tag = null;
31+
32+
$algorithm = new A128GCM();
33+
34+
$cek = random_bytes(128 / 8);
35+
$iv = random_bytes(96 / 8);
36+
$plaintext = 'Live long and Prosper.';
37+
38+
$cyphertext = $algorithm->encryptContent($plaintext, $cek, $iv, null, $header, $tag);
39+
40+
self::assertNotNull($tag);
41+
self::assertEquals($plaintext, $algorithm->decryptContent($cyphertext, $cek, $iv, null, $header, $tag));
42+
}
43+
44+
public function testA192GCMEncryptAndDecrypt()
45+
{
46+
$header = Base64Url::encode(json_encode(['alg' => 'ECDH-ES', 'enc' => 'A192GCM']));
47+
$tag = null;
48+
49+
$algorithm = new A192GCM();
50+
51+
$cek = random_bytes(192 / 8);
52+
$iv = random_bytes(96 / 8);
53+
$plaintext = 'Live long and Prosper.';
54+
55+
$cyphertext = $algorithm->encryptContent($plaintext, $cek, $iv, null, $header, $tag);
56+
57+
self::assertNotNull($tag);
58+
self::assertEquals($plaintext, $algorithm->decryptContent($cyphertext, $cek, $iv, null, $header, $tag));
59+
}
60+
61+
public function testA256GCMEncryptAndDecrypt()
62+
{
63+
$header = Base64Url::encode(json_encode(['alg' => 'ECDH-ES', 'enc' => 'A256GCM']));
64+
$tag = null;
65+
66+
$algorithm = new A256GCM();
67+
68+
$cek = random_bytes(256 / 8);
69+
$iv = random_bytes(96 / 8);
70+
$plaintext = 'Live long and Prosper.';
71+
72+
$cyphertext = $algorithm->encryptContent($plaintext, $cek, $iv, null, $header, $tag);
73+
74+
self::assertNotNull($tag);
75+
self::assertEquals($plaintext, $algorithm->decryptContent($cyphertext, $cek, $iv, null, $header, $tag));
76+
}
77+
78+
/**
79+
* @see https://tools.ietf.org/html/rfc7516#appendix-A.1
80+
*/
81+
public function testA256GCMDecryptTestVector()
82+
{
83+
$algorithm = new A256GCM();
84+
85+
$header = Base64Url::encode(json_encode(['alg' => 'RSA-OAEP', 'enc' => 'A256GCM']));
86+
$cek = $this->convertArrayToBinString([177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154, 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122, 234, 64, 252]);
87+
$iv = $this->convertArrayToBinString([227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219]);
88+
$tag = $this->convertArrayToBinString([92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145]);
89+
$cyphertext = $this->convertArrayToBinString([229, 236, 166, 241, 53, 191, 115, 196, 174, 43, 73, 109, 39, 122, 233, 96, 140, 206, 120, 52, 51, 237, 48, 11, 190, 219, 186, 80, 111, 104, 50, 142, 47, 167, 59, 61, 181, 127, 196, 21, 40, 82, 242, 32, 123, 143, 168, 226, 73, 216, 176, 144, 138, 247, 106, 60, 16, 205, 160, 109, 64, 63, 192]);
90+
$expected_plaintext = 'The true sign of intelligence is not knowledge but imagination.';
91+
92+
self::assertEquals('eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ', $header);
93+
self::assertEquals($expected_plaintext, $algorithm->decryptContent($cyphertext, $cek, $iv, null, $header, $tag));
94+
}
95+
96+
/**
97+
* @param array $data
98+
*
99+
* @return string
100+
*/
101+
private function convertArrayToBinString(array $data): string
102+
{
103+
foreach ($data as $key => $value) {
104+
$data[$key] = str_pad(dechex($value), 2, '0', STR_PAD_LEFT);
105+
}
106+
107+
return hex2bin(implode('', $data));
108+
}
109+
}

‎composer.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "web-token/jwt-encryption-algorithm-aesgcm",
3+
"description": "AES GCM Based Content Encryption Algorithms the JWT Framework.",
4+
"type": "library",
5+
"license": "MIT",
6+
"keywords": ["JWS", "JWT", "JWE", "JWA", "JWK", "JWKSet", "Jot", "Jose", "RFC7515", "RFC7516", "RFC7517", "RFC7518", "RFC7519", "RFC7520", "Bundle", "Symfony"],
7+
"homepage": "https://github.com/web-token",
8+
"authors": [
9+
{
10+
"name": "Florent Morselli",
11+
"homepage": "https://github.com/Spomky"
12+
},{
13+
"name": "All contributors",
14+
"homepage": "https://github.com/web-token/jwt-core/contributors"
15+
}
16+
],
17+
"autoload": {
18+
"psr-4": {
19+
"Jose\\Component\\Encryption\\Algorithm\\ContentEncryption\\": ""
20+
}
21+
},
22+
"require": {
23+
"web-token/jwt-encryption": "^1.2"
24+
},
25+
"require-dev": {
26+
"phpunit/phpunit": "^6.0|^7.0"
27+
},
28+
"extra": {
29+
"branch-alias": {
30+
"dev-master": "1.2.x-dev"
31+
}
32+
},
33+
"config": {
34+
"sort-packages": true
35+
}
36+
}

‎phpunit.xml.dist

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit
3+
backupGlobals="false"
4+
backupStaticAttributes="false"
5+
convertErrorsToExceptions="true"
6+
convertNoticesToExceptions="true"
7+
convertWarningsToExceptions="true"
8+
processIsolation="false"
9+
stopOnFailure="false"
10+
syntaxCheck="true"
11+
bootstrap="vendor/autoload.php"
12+
colors="true">
13+
<testsuites>
14+
<testsuite name="Test Suite">
15+
<directory>./Tests/</directory>
16+
</testsuite>
17+
</testsuites>
18+
19+
<filter>
20+
<whitelist>
21+
<directory suffix=".php">./</directory>
22+
<exclude>
23+
<directory>./vendor</directory>
24+
<directory>./Tests</directory>
25+
<directory suffix="Test.php">./src</directory>
26+
</exclude>
27+
</whitelist>
28+
</filter>
29+
</phpunit>

0 commit comments

Comments
 (0)
Please sign in to comment.