1<?php
2
3namespace Defuse\Crypto;
4
5use Defuse\Crypto\Exception as Ex;
6
7final class Key
8{
9    const KEY_CURRENT_VERSION = "\xDE\xF0\x00\x00";
10    const KEY_BYTE_SIZE       = 32;
11
12    /**
13     * @var string
14     */
15    private $key_bytes;
16
17    /**
18     * Creates new random key.
19     *
20     * @throws Ex\EnvironmentIsBrokenException
21     *
22     * @return Key
23     */
24    public static function createNewRandomKey()
25    {
26        return new Key(Core::secureRandom(self::KEY_BYTE_SIZE));
27    }
28
29    /**
30     * Loads a Key from its encoded form.
31     *
32     * By default, this function will call Encoding::trimTrailingWhitespace()
33     * to remove trailing CR, LF, NUL, TAB, and SPACE characters, which are
34     * commonly appended to files when working with text editors.
35     *
36     * @param string $saved_key_string
37     * @param bool $do_not_trim (default: false)
38     *
39     * @throws Ex\BadFormatException
40     * @throws Ex\EnvironmentIsBrokenException
41     *
42     * @return Key
43     */
44    public static function loadFromAsciiSafeString($saved_key_string, $do_not_trim = false)
45    {
46        if (!$do_not_trim) {
47            $saved_key_string = Encoding::trimTrailingWhitespace($saved_key_string);
48        }
49        $key_bytes = Encoding::loadBytesFromChecksummedAsciiSafeString(self::KEY_CURRENT_VERSION, $saved_key_string);
50        return new Key($key_bytes);
51    }
52
53    /**
54     * Encodes the Key into a string of printable ASCII characters.
55     *
56     * @throws Ex\EnvironmentIsBrokenException
57     *
58     * @return string
59     */
60    public function saveToAsciiSafeString()
61    {
62        return Encoding::saveBytesToChecksummedAsciiSafeString(
63            self::KEY_CURRENT_VERSION,
64            $this->key_bytes
65        );
66    }
67
68    /**
69     * Gets the raw bytes of the key.
70     *
71     * @return string
72     */
73    public function getRawBytes()
74    {
75        return $this->key_bytes;
76    }
77
78    /**
79     * Constructs a new Key object from a string of raw bytes.
80     *
81     * @param string $bytes
82     *
83     * @throws Ex\EnvironmentIsBrokenException
84     */
85    private function __construct($bytes)
86    {
87        Core::ensureTrue(
88            Core::ourStrlen($bytes) === self::KEY_BYTE_SIZE,
89            'Bad key length.'
90        );
91        $this->key_bytes = $bytes;
92    }
93
94}
95