ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
TokenTest.php
Go to the documentation of this file.
1<?php
2
20
21use PHPUnit\Framework\Attributes\DataProvider;
22use PHPUnit\Framework\TestCase;
31
35class TokenTest extends TestCase
36{
37 public function testSomething(): void
38 {
39 $data_signer = new DataSigner(
41 new SecretKey('test_key_one')
42 ),
43 new SHA1()
44 );
45
46 $payload_data = [
47 't' => 1,
48 'p' => 'fsv2/63a/6a5/5a2/1cf42b2ad0bc1ee729a5965/1/data',
49 'u' => 6
50 ];
51
52 $singed_data = $data_signer->sign($payload_data, 'test_salt', new \DateTimeImmutable('2099-01-01 00:00:00'));
53
54 $this->assertIsString($singed_data);
55 $this->assertSame(
56 'Fck5CsMwEEDRu0xt0GySJWF8EjWjrTbESRNy98jNh8f_wg2ZNrggw3x9uLggtmK-OG-L1KZyZetYG42xczKfwrpUXLfbYIM35PA7jvNU3DFhjIiPRpjapabGlTj2JsJch8rQmJ5lUVUo0B8',
57 $singed_data
58 );
59 $this->assertSame(143, strlen($singed_data));
60
61 $retrieve = $data_signer->verify($singed_data, 'test_salt');
62 $this->assertSame($payload_data, $retrieve);
63 }
64
65 public static function providePayloads(): \Iterator
66 {
67 $random = static function (int $chars): string {
68 for ($i = 0, $str = ''; $i < $chars; $i++) {
69 $str .= chr(random_int(33, 125));
70 }
71 return $str;
72 };
73 yield ['lorem ipsum'];
74 yield ['o@3z||w^h\F(G[Z,*qjo/n8$Q_yO({,%9h4]UK&s*E$H=/8L6:#2VDFb5<Is%;=3p=2\'xb{skeOKw^Pt]wwya$6JV_e{7qbZUmcl{V3JRl<w{N=M_512x4DV=>i]=2$X+od8+#KVG+mN"9yHWW+RGb>eDZ\+RW>\%ks2yj%m)29=)cpLT8w4{rBl]Yvx%njk3?)Mrc-|`Dd4I)F?y;f2%-W/ObD?v"TWk(:pHN4?FXTeT7f@{[)N/2XQW@c<ddk6\'b&;R;bcB8@W)[l(7RCvUU1EE4>[CN1w1.U1`+LVUKZaN_v<?CUAjTXe=B-@4c\'$.kB;HjI)\03<ll29`o_0$U@KF8JQH8=pQ^j>i:+R&m\jOOuys3"Ow|out8=[vM\^an:|^NZE-za668{I\'YPwXpIONsa"+fwjn)nj%{b$2{gZoljdq4:MA?I&dz9d;K-9t%A%8,@9rLwF1tuMxx@f{NoH+J[;PVRByLz&Z9,)wNXS"wO|eD%e$0wDW\Ie*fQsSHSuU(S8W9O8RNc+VQVbJAKC+0#gYHBBFtNPDKn#XvyhsOTEi/+lAO5\HA=PvG<g{d$lP;^|A1a^BvaJH:k|U88KH<34ub`S*J92Sw>(tTt{#/*\'%dAcdm$JJ<6MP+J4.ifdi-D_<`)D1Xf(O6rxB>$HCw9IVR/lJ]7eK1q&:.z7mUi4C@W+/d-35\:GdeL4Yu9jEvbL)yd9{49FXx<iV4]_HoF(CLySJm^l3eX|||_"RV*+[\'M\+8O]xlzfTalIE3;<)cS9">?RbuKY^N4Y[o^lr5\'8O55skRBGli:&Kq75WPT(w#Zpj]_UMluSs:"e_(SRX?%4<m,8H:`fH@hR(i9sIz6spfcp8igK5IXp`Vx1=Lv?Ast"m2nvGs4O^/VoN-Aqn`SflY+QSB+XIcJ1@2rA5[GNnN3{zkb*<MXz/\'\'X\'n=e&F>4nVQ`Fb0"WNvi)ZYbY]/%aDN>wMlT)M\=XGk^[2H?pgf8#BrC"A:bj2=Qfm^#2ZegzFBYV.E,b,xC_;<{P.ps*Vm&ErnTp|)qMOV:GBXH\l?6x?S]hUV.$CESk/ns/Zg5NGrC/$\'f>\'tVY{"Oa(DB@UN#yVh@n6JZ$F*(q)Ty]^.OTmAXSX^f\'j_1q80sB]2q^?<f2<(7=0[_l^i;HrU.$NgqgIy/N?hN-6IgL=:Z(tX\+A\B*{QJTT\'LY{tD:5S)t^Vcn=PC$;5*<^2@/3Ahgw&,`JQ0+a-JnB\+H/Kc|pF<\'(q6d\uz?_?<yyICy6+|jpK{LJ`UT>f*\'BLsv*AvoH|ET07EiO"xFh/{[+>=xT9DnLh0F>j#L(B&iBxaq6mW%TO"[]W]pIM{:Y]tQK4@TO[O>qg{eSr4W:Vkp6#ECM+&O>5uH3##]#?d4mV(?wJt;Jb|TXCD?t<BNV"%p#KB)H=i0y\'z%Rf)0Dp{JE*0zGY<KG)gMDylE;_1PukRAe)qxfSd{uA`8\vqpzfcaM6_gYDwy_w-JQf=z;-UnxvF";Sf;OnCIGm3-/0S$1jPuFb:n_9=pu\'jE3A6Ne)FxN@3An5x/EwiOTYQ-6w;rYA>4_zldc\'"0g=hYUVIQ=U7B@>+`@hN#HNV\'Z6ul2UL-/eld6xGeDV)s@.)B9t2LS+rmM?ZREmV.coe-SUkLV)Wp-sO/SWeeF..zi\Yj3pNqx(j6"#B@St]M@>:k-sb#h(5RRP2%jeVP5KM\a\Q.n#T"Z0qpcsD6/WQ|GbuhK84<C[GCjN+@>VE7WZFM)O1@]bhl;{@q4aQ?\Vv%hv3;CG]J%+N\'J9]_=N8iI?Y:l4I%?0W?,iI5V,Fqq(Zz&4vH1c"|&82YMVhx0?Wk:dFf\mZv%BkX6K9?{+6w:ikAUq7cw1oYin\'{"ayy/sZ`oF[aFa=_mO/EG-Is\'6Ks{Dg#Q\'@XCw&YSUHE1UP9ITeJL`R%]=-;qY%*#]-rcq;+iOPT\V/(iO(6GhjW/dA2fD&dxwVS*I(gQx4V6\'K;I0e\'P5cY<P]=u>Ck9dS"I]iOnX)<?P7\DB;9MkJ|5zld9=hxQAJ5XVfp*F0e.SDl|""'];
75 yield [$random(1024)];
76 yield [$random(2048)];
77 yield [$random(4094)];
78 yield [$random(8192)];
79 yield [$random(16384)];
80 yield [$random(32768)];
81 }
82
83 #[DataProvider('providePayloads')]
84 public function testLargeAmountOfData(string $data): void
85 {
86 $datasigner = new DataSigner(
88 new SecretKey('test_key_one'),
89 )
90 );
91
92 $singed_data = $datasigner->sign([$data], 'salt');
93 $verified_data = $datasigner->verify($singed_data, 'salt');
94
95 if ($verified_data === null) {
96 $this->fail('Could not verify data');
97 }
98
99 $this->assertNotNull($verified_data);
100 $this->assertSame([$data], $verified_data);
101 $this->assertSame($singed_data, urlencode($singed_data));
102 $signed_data_without_suffix = rtrim($singed_data, '=');
103 $this->assertSame($signed_data_without_suffix, urlencode($signed_data_without_suffix));
104 }
105
106 public function testExpiredTokens(): void
107 {
108 $datasigner = new DataSigner(
110 new SecretKey('test_key_one'),
111 )
112 );
113
114 $singed_data = $datasigner->sign(['a', 'b', 'c'], 'salt', new \DateTimeImmutable('-1 day'));
115 $verified_data = $datasigner->verify($singed_data, 'salt');
116
117 $this->assertNull($verified_data);
118
119 $singed_data = $datasigner->sign(['a', 'b', 'c'], 'salt', new \DateTimeImmutable('-1 second'));
120 $verified_data = $datasigner->verify($singed_data, 'salt');
121
122 $this->assertNull($verified_data);
123
124 $singed_data = $datasigner->sign(['a', 'b', 'c'], 'salt', new \DateTimeImmutable('+1 second'));
125 $verified_data = $datasigner->verify($singed_data, 'salt');
126
127 $this->assertNotNull($verified_data);
128 }
129
130 public function testKeyRotation(): void
131 {
132 $salt = new Salt('test_salt');
133
134 $key_rotation = new SecretKeyRotation(
135 new SecretKey('test_key_one'),
136 );
137 $rotating_signer = new KeyRotatingSigner(
138 $key_rotation,
139 new NullSigner(),
141 $salt
142 );
143
144 $payload = 'singed_data_one';
145 $signature = $rotating_signer->sign($payload, $salt);
146 $this->assertTrue($rotating_signer->verify($payload, $signature, 0, $salt));
147
148 $key_rotation = new SecretKeyRotation(
149 new SecretKey('test_key_two'),
150 new SecretKey('test_key_one'),
151 );
152 $rotating_signer = new KeyRotatingSigner(
153 $key_rotation,
154 new NullSigner(),
156 $salt
157 );
158 $this->assertTrue($rotating_signer->verify($payload, $signature, 0, $salt));
159
160 $key_rotation = new SecretKeyRotation(
161 new SecretKey('test_key_three'),
162 new SecretKey('test_key_two'),
163 );
164 $rotating_signer = new KeyRotatingSigner(
165 $key_rotation,
166 new NullSigner(),
168 $salt
169 );
170 $this->assertFalse($rotating_signer->verify($payload, $signature, 0, $salt));
171 }
172}
Key rotation can provide an extra layer of mitigation against an attacker discovering a secret key.
Signatures are secured by the secret_key.
Definition: SecretKey.php:40
The salt is combined with the secret key to derive a unique key for distinguishing different contexts...
Definition: Salt.php:38
if(count($parts) !=3) $payload
Definition: ltitoken.php:67
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: TokenTest.php:19