2
2
3
3
declare (strict_types=1 );
4
4
5
- /*
6
- * The MIT License (MIT)
7
- *
8
- * Copyright (c) 2014-2020 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
5
namespace Jose \Component \Encryption \Algorithm \KeyEncryption \Util ;
15
6
16
7
use function chr ;
17
8
use function count ;
18
9
use InvalidArgumentException ;
19
- use function is_array ;
20
10
use Jose \Component \Core \Util \BigInteger ;
21
11
use Jose \Component \Core \Util \Hash ;
22
12
use Jose \Component \Core \Util \RSAKey ;
23
13
use function ord ;
24
14
use RuntimeException ;
15
+ use const STR_PAD_LEFT ;
25
16
26
17
/**
27
18
* @internal
28
19
*/
29
- class RSACrypt
20
+ final class RSACrypt
30
21
{
31
22
/**
32
23
* Optimal Asymmetric Encryption Padding (OAEP).
@@ -40,30 +31,20 @@ class RSACrypt
40
31
41
32
public static function encrypt (RSAKey $ key , string $ data , int $ mode , ?string $ hash = null ): string
42
33
{
43
- switch ($ mode ) {
44
- case self ::ENCRYPTION_OAEP :
45
- return self ::encryptWithRSAOAEP ($ key , $ data , $ hash );
46
-
47
- case self ::ENCRYPTION_PKCS1 :
48
- return self ::encryptWithRSA15 ($ key , $ data );
49
-
50
- default :
51
- throw new InvalidArgumentException ('Unsupported mode. ' );
52
- }
34
+ return match ($ mode ) {
35
+ self ::ENCRYPTION_OAEP => self ::encryptWithRSAOAEP ($ key , $ data , $ hash ),
36
+ self ::ENCRYPTION_PKCS1 => self ::encryptWithRSA15 ($ key , $ data ),
37
+ default => throw new InvalidArgumentException ('Unsupported mode. ' ),
38
+ };
53
39
}
54
40
55
41
public static function decrypt (RSAKey $ key , string $ plaintext , int $ mode , ?string $ hash = null ): string
56
42
{
57
- switch ($ mode ) {
58
- case self ::ENCRYPTION_OAEP :
59
- return self ::decryptWithRSAOAEP ($ key , $ plaintext , $ hash );
60
-
61
- case self ::ENCRYPTION_PKCS1 :
62
- return self ::decryptWithRSA15 ($ key , $ plaintext );
63
-
64
- default :
65
- throw new InvalidArgumentException ('Unsupported mode. ' );
66
- }
43
+ return match ($ mode ) {
44
+ self ::ENCRYPTION_OAEP => self ::decryptWithRSAOAEP ($ key , $ plaintext , $ hash ),
45
+ self ::ENCRYPTION_PKCS1 => self ::decryptWithRSA15 ($ key , $ plaintext ),
46
+ default => throw new InvalidArgumentException ('Unsupported mode. ' ),
47
+ };
67
48
}
68
49
69
50
public static function encryptWithRSA15 (RSAKey $ key , string $ data ): string
@@ -81,7 +62,7 @@ public static function encryptWithRSA15(RSAKey $key, string $data): string
81
62
$ ps .= $ temp ;
82
63
}
83
64
$ type = 2 ;
84
- $ data = chr (0 ). chr ($ type ). $ ps. chr (0 ). $ data ;
65
+ $ data = chr (0 ) . chr ($ type ) . $ ps . chr (0 ) . $ data ;
85
66
86
67
$ data = BigInteger::createFromBinaryString ($ data );
87
68
$ c = self ::getRSAEP ($ key , $ data );
@@ -97,7 +78,7 @@ public static function decryptWithRSA15(RSAKey $key, string $c): string
97
78
$ c = BigInteger::createFromBinaryString ($ c );
98
79
$ m = self ::getRSADP ($ key , $ c );
99
80
$ em = self ::convertIntegerToOctetString ($ m , $ key ->getModulusLength ());
100
- if (0 !== ord ($ em [0 ]) || ord ($ em [1 ]) > 2 ) {
81
+ if (ord ($ em [0 ]) !== 0 || ord ($ em [1 ]) > 2 ) {
101
82
throw new InvalidArgumentException ('Unable to decrypt ' );
102
83
}
103
84
$ ps = mb_substr ($ em , 2 , (int ) mb_strpos ($ em , chr (0 ), 2 , '8bit ' ) - 2 , '8bit ' );
@@ -117,15 +98,12 @@ public static function encryptWithRSAOAEP(RSAKey $key, string $plaintext, string
117
98
/** @var Hash $hash */
118
99
$ hash = Hash::$ hash_algorithm ();
119
100
$ length = $ key ->getModulusLength () - 2 * $ hash ->getLength () - 2 ;
120
- if (0 >= $ length ) {
101
+ if ($ length <= 0 ) {
121
102
throw new RuntimeException ();
122
103
}
123
- $ plaintext = mb_str_split ($ plaintext , $ length , '8bit ' );
124
- if (!is_array ($ plaintext )) {
125
- throw new RuntimeException ('Invalid payload ' );
126
- }
104
+ $ splitPlaintext = mb_str_split ($ plaintext , $ length , '8bit ' );
127
105
$ ciphertext = '' ;
128
- foreach ($ plaintext as $ m ) {
106
+ foreach ($ splitPlaintext as $ m ) {
129
107
$ ciphertext .= self ::encryptRSAESOAEP ($ key , $ m , $ hash );
130
108
}
131
109
@@ -137,17 +115,19 @@ public static function encryptWithRSAOAEP(RSAKey $key, string $plaintext, string
137
115
*/
138
116
public static function decryptWithRSAOAEP (RSAKey $ key , string $ ciphertext , string $ hash_algorithm ): string
139
117
{
140
- if (0 >= $ key ->getModulusLength ()) {
118
+ if ($ key ->getModulusLength () <= 0 ) {
141
119
throw new RuntimeException ('Invalid modulus length ' );
142
120
}
143
121
$ hash = Hash::$ hash_algorithm ();
144
- $ ciphertext = mb_str_split ($ ciphertext , $ key ->getModulusLength (), '8bit ' );
145
- if (!is_array ($ ciphertext )) {
146
- throw new RuntimeException ('Invalid ciphertext ' );
147
- }
148
- $ ciphertext [count ($ ciphertext ) - 1 ] = str_pad ($ ciphertext [count ($ ciphertext ) - 1 ], $ key ->getModulusLength (), chr (0 ), STR_PAD_LEFT );
122
+ $ splitCiphertext = mb_str_split ($ ciphertext , $ key ->getModulusLength (), '8bit ' );
123
+ $ splitCiphertext [count ($ splitCiphertext ) - 1 ] = str_pad (
124
+ $ splitCiphertext [count ($ splitCiphertext ) - 1 ],
125
+ $ key ->getModulusLength (),
126
+ chr (0 ),
127
+ STR_PAD_LEFT
128
+ );
149
129
$ plaintext = '' ;
150
- foreach ($ ciphertext as $ c ) {
130
+ foreach ($ splitCiphertext as $ c ) {
151
131
$ temp = self ::getRSAESOAEP ($ key , $ c , $ hash );
152
132
$ plaintext .= $ temp ;
153
133
}
@@ -206,7 +186,7 @@ private static function getMGF1(string $mgfSeed, int $maskLen, Hash $mgfHash): s
206
186
$ count = ceil ($ maskLen / $ mgfHash ->getLength ());
207
187
for ($ i = 0 ; $ i < $ count ; ++$ i ) {
208
188
$ c = pack ('N ' , $ i );
209
- $ t .= $ mgfHash ->hash ($ mgfSeed. $ c );
189
+ $ t .= $ mgfHash ->hash ($ mgfSeed . $ c );
210
190
}
211
191
212
192
return mb_substr ($ t , 0 , $ maskLen , '8bit ' );
@@ -220,13 +200,13 @@ private static function encryptRSAESOAEP(RSAKey $key, string $m, Hash $hash): st
220
200
$ mLen = mb_strlen ($ m , '8bit ' );
221
201
$ lHash = $ hash ->hash ('' );
222
202
$ ps = str_repeat (chr (0 ), $ key ->getModulusLength () - $ mLen - 2 * $ hash ->getLength () - 2 );
223
- $ db = $ lHash. $ ps. chr (1 ). $ m ;
203
+ $ db = $ lHash . $ ps . chr (1 ) . $ m ;
224
204
$ seed = random_bytes ($ hash ->getLength ());
225
205
$ dbMask = self ::getMGF1 ($ seed , $ key ->getModulusLength () - $ hash ->getLength () - 1 , $ hash/*MGF*/ );
226
206
$ maskedDB = $ db ^ $ dbMask ;
227
207
$ seedMask = self ::getMGF1 ($ maskedDB , $ hash ->getLength (), $ hash/*MGF*/ );
228
208
$ maskedSeed = $ seed ^ $ seedMask ;
229
- $ em = chr (0 ). $ maskedSeed. $ maskedDB ;
209
+ $ em = chr (0 ) . $ maskedSeed . $ maskedDB ;
230
210
231
211
$ m = self ::convertOctetStringToInteger ($ em );
232
212
$ c = self ::getRSAEP ($ key , $ m );
@@ -251,11 +231,11 @@ private static function getRSAESOAEP(RSAKey $key, string $c, Hash $hash): string
251
231
$ db = $ maskedDB ^ $ dbMask ;
252
232
$ lHash2 = mb_substr ($ db , 0 , $ hash ->getLength (), '8bit ' );
253
233
$ m = mb_substr ($ db , $ hash ->getLength (), null , '8bit ' );
254
- if (!hash_equals ($ lHash , $ lHash2 )) {
234
+ if (! hash_equals ($ lHash , $ lHash2 )) {
255
235
throw new RuntimeException ();
256
236
}
257
237
$ m = ltrim ($ m , chr (0 ));
258
- if (1 !== ord ($ m [0 ])) {
238
+ if (ord ($ m [0 ]) !== 1 ) {
259
239
throw new RuntimeException ();
260
240
}
261
241
0 commit comments