SymmetricKey   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 69
rs 10
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 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
        protected string $material,
32
    ) {
33
    }
34
35
36
    /**
37
     * Return the key material associated with this key.
38
     *
39
     * @return string The key material.
40
     */
41
    public function getMaterial(): string
42
    {
43
        return $this->material;
44
    }
45
46
47
    /**
48
     * Generate a random, binary secret key of a given length.
49
     *
50
     * If the key is intended to be used with 3DES in CBC mode, pass true in $parityBits.
51
     *
52
     * @param positive-int $length The length of the secret we want, in bytes.
53
     * @param bool $parityBits Whether the key should be suitable for its use in 3DES in CBC mode or not.
54
     *
55
     * @return \SimpleSAML\XMLSecurity\Key\SymmetricKey A cryptographically-secure random symmetric key.
56
     *
57
     * @throws \SimpleSAML\XMLSecurity\Exception\RuntimeException If no appropriate sources of cryptographically-secure
58
     *   random material are available.
59
     */
60
    public static function generate(int $length, bool $parityBits = false): SymmetricKey
61
    {
62
        $key = Random::generateRandomBytes($length);
63
64
        if ($parityBits) {
65
            /*
66
             * Make sure that the generated key has the proper parity bits set.
67
             * Mcrypt doesn't care about the parity bits, but others may care.
68
             */
69
            for ($i = 0; $i < strlen($key); $i++) {
70
                $byte = ord($key[$i]) & 0xfe;
71
                $parity = 1;
72
                for ($j = 1; $j < 8; $j++) {
73
                    $parity ^= ($byte >> $j) & 1;
74
                }
75
                $byte |= $parity;
76
                $key[$i] = chr($byte);
77
            }
78
        }
79
80
        return new self($key);
81
    }
82
83
84
    /**
85
     * Get the length of this symmetric key, in bytes.
86
     *
87
     * @return int The length of the key.
88
     */
89
    public function getLength(): int
90
    {
91
        return strlen($this->getMaterial());
92
    }
93
}
94