Passed
Push — master ( 4222c9...84ca1d )
by Tony Karavasilev (Тони
21:38
created

AbstractStreamCipherAlgorithm::encryptData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
/**
4
 * The symmetric stream cipher encryption algorithm abstraction specification.
5
 */
6
7
namespace CryptoManana\Core\Abstractions\MessageEncryption;
8
9
use \CryptoManana\Core\Abstractions\MessageEncryption\AbstractSymmetricEncryptionAlgorithm as SymmetricCipherAlgorithm;
10
use \CryptoManana\Core\Interfaces\MessageEncryption\ObjectEncryptionInterface as ObjectEncryption;
11
use \CryptoManana\Core\Interfaces\MessageEncryption\FileEncryptionInterface as FileEncryption;
12
use \CryptoManana\Core\Traits\MessageEncryption\ObjectEncryptionTrait as EncryptObjects;
13
use \CryptoManana\Core\Traits\MessageEncryption\FileEncryptionTrait as EncryptFiles;
14
15
/**
16
 * Class AbstractStreamCipherAlgorithm - The symmetric stream cipher algorithm abstraction representation.
17
 *
18
 * @package CryptoManana\Core\Abstractions\MessageEncryption
19
 *
20
 * @mixin EncryptObjects
21
 * @mixin EncryptFiles
22
 */
23
abstract class AbstractStreamCipherAlgorithm extends SymmetricCipherAlgorithm implements
24
    ObjectEncryption,
25
    FileEncryption
26
{
27
    /**
28
     * Object encryption and decryption capabilities.
29
     *
30
     * {@internal Reusable implementation of `ObjectEncryptionInterface`. }}
31
     */
32
    use EncryptObjects;
33
34
    /**
35
     * File content encryption and decryption capabilities.
36
     *
37
     * {@internal Reusable implementation of `FileEncryptionInterface`. }}
38
     */
39
    use EncryptFiles;
40
41
    /**
42
     * Fetch the correctly formatted internal encryption algorithm method name.
43
     *
44
     * @return string The symmetric encryption algorithm standard.
45
     */
46 50
    protected function fetchAlgorithmMethodName()
47
    {
48 50
        return static::ALGORITHM_NAME;
49
    }
50
51
    /**
52
     * Internal method for the validation of plain data used at encryption operations.
53
     *
54
     * @param string $plainData The plain input string.
55
     *
56
     * @throws \Exception Validation errors.
57
     */
58 22
    protected function validatePlainDataForEncryption($plainData)
59
    {
60 22
        if (!is_string($plainData)) {
61 2
            throw new \InvalidArgumentException('The data for encryption must be a string or a binary string.');
62
        }
63 20
    }
64
65
    /**
66
     * Internal method for the validation of cipher data used at decryption operations.
67
     *
68
     * @param string $cipherData The encrypted input string.
69
     *
70
     * @throws \Exception Validation errors.
71
     */
72 18
    protected function validateCipherDataForDecryption($cipherData)
73
    {
74 18
        if (!is_string($cipherData)) {
75 2
            throw new \InvalidArgumentException('The data for decryption must be a string or a binary string.');
76 16
        } elseif ($cipherData === '') {
77 2
            throw new \InvalidArgumentException('The string is empty and there is nothing to decrypt from it.');
78
        }
79 14
    }
80
81
    /**
82
     * Stream cipher algorithm constructor.
83
     */
84 50
    public function __construct()
85
    {
86
        /**
87
         * {@internal Serialization and initialization purposes for the default key. }}
88
         */
89 50
        if (strlen($this->key) < static::KEY_SIZE) {
90 50
            $this->key = str_pad($this->key, static::KEY_SIZE, "\x0", STR_PAD_RIGHT);
91
        }
92
93
        // @codeCoverageIgnoreStart
94
        if (!in_array($this->fetchAlgorithmMethodName(), openssl_get_cipher_methods(), true)) {
95
            throw new \RuntimeException(
96
                'The algorithm `' .
97
                $this->fetchAlgorithmMethodName() .
98
                '`is not supported under the current system configuration.'
99
            );
100
        }
101
        // @codeCoverageIgnoreEnd
102 50
    }
103
104
    /**
105
     * Encrypts the given plain data.
106
     *
107
     * @param string $plainData The plain input string.
108
     *
109
     * @return string The cipher/encrypted data.
110
     * @throws \Exception Validation errors.
111
     */
112 4
    public function encryptData($plainData)
113
    {
114 4
        $this->validatePlainDataForEncryption($plainData);
115
116 4
        $plainData = ($plainData === '') ? ' ' : $plainData;
117
118 4
        $cipherData = openssl_encrypt($plainData, $this->fetchAlgorithmMethodName(), $this->key, OPENSSL_RAW_DATA, '');
119
120 4
        return $this->changeOutputFormat($cipherData, true);
121
    }
122
123
    /**
124
     * Decrypts the given cipher data.
125
     *
126
     * @param string $cipherData The encrypted input string.
127
     *
128
     * @return string The decrypted/plain data.
129
     * @throws \Exception Validation errors.
130
     */
131 4
    public function decryptData($cipherData)
132
    {
133 4
        $this->validateCipherDataForDecryption($cipherData);
134
135 4
        $cipherData = $this->changeOutputFormat($cipherData, false);
136
137 4
        $plainData = openssl_decrypt($cipherData, $this->fetchAlgorithmMethodName(), $this->key, OPENSSL_RAW_DATA, '');
138
139 4
        return ($plainData === false) ? '' : $plainData;
140
    }
141
142
    /**
143
     * Get debug information for the class instance.
144
     *
145
     * @return array Debug information.
146
     */
147 2
    public function __debugInfo()
148
    {
149
        return [
150 2
            'standard' => static::ALGORITHM_NAME,
151 2
            'type' => 'symmetrical encryption or two-way stream cipher',
152 2
            'key size in bits' => static::KEY_SIZE * 8,
153 2
            'secret key' => $this->key,
154 2
            'internal algorithm full name' => $this->fetchAlgorithmMethodName(),
155 2
            'internal long data digestion algorithm' => 'HKDF-SHA-2-128',
156
        ];
157
    }
158
}
159