SymmetricKey   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 7
eloc 12
c 1
b 0
f 0
dl 0
loc 70
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getMaterial() 0 3 1
A generate() 0 21 4
A getLength() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\Key;
6
7
use SimpleSAML\XMLSecurity\Utils\Random;
8
9
use function chr;
10
use function ord;
11
use function strlen;
12
13
/**
14
 * A class to model symmetric key secrets.
15
 *
16
 * New SymmetricKey objects can be created passing a given secret to the constructor, or using the static method
17
 * generate(), which will return a SymmetricKey object with a random secret material.
18
 *
19
 * Note that random secrets generated by this class will be cryptographically secure.
20
 *
21
 * @package simplesamlphp/xml-security
22
 */
23
class SymmetricKey implements KeyInterface
24
{
25
    /**
26
     * Build a new key with $key as its material.
27
     *
28
     * @param string $material The associated key material.
29
     */
30
    public function __construct(
31
        #[\SensitiveParameter]
32
        protected string $material,
33
    ) {
34
    }
35
36
37
    /**
38
     * Return the key material associated with this key.
39
     *
40
     * @return string The key material.
41
     */
42
    public function getMaterial(): string
43
    {
44
        return $this->material;
45
    }
46
47
48
    /**
49
     * Generate a random, binary secret key of a given length.
50
     *
51
     * If the key is intended to be used with 3DES in CBC mode, pass true in $parityBits.
52
     *
53
     * @param positive-int $length The length of the secret we want, in bytes.
54
     * @param bool $parityBits Whether the key should be suitable for its use in 3DES in CBC mode or not.
55
     *
56
     * @return \SimpleSAML\XMLSecurity\Key\SymmetricKey A cryptographically-secure random symmetric key.
57
     *
58
     * @throws \SimpleSAML\XMLSecurity\Exception\RuntimeException If no appropriate sources of cryptographically-secure
59
     *   random material are available.
60
     */
61
    public static function generate(int $length, bool $parityBits = false): SymmetricKey
62
    {
63
        $key = Random::generateRandomBytes($length);
64
65
        if ($parityBits) {
66
            /*
67
             * Make sure that the generated key has the proper parity bits set.
68
             * Mcrypt doesn't care about the parity bits, but others may care.
69
             */
70
            for ($i = 0; $i < strlen($key); $i++) {
71
                $byte = ord($key[$i]) & 0xfe;
72
                $parity = 1;
73
                for ($j = 1; $j < 8; $j++) {
74
                    $parity ^= ($byte >> $j) & 1;
75
                }
76
                $byte |= $parity;
77
                $key[$i] = chr($byte);
78
            }
79
        }
80
81
        return new self($key);
82
    }
83
84
85
    /**
86
     * Get the length of this symmetric key, in bytes.
87
     *
88
     * @return int The length of the key.
89
     */
90
    public function getLength(): int
91
    {
92
        return strlen($this->getMaterial());
93
    }
94
}
95