aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/CoreBundle/Helper/CryptoProxy.php
blob: 7d8c9888800d445be8ccf891bf57f780a04d3c3d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php

namespace Wallabag\CoreBundle\Helper;

use Defuse\Crypto\Crypto;
use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException;
use Defuse\Crypto\Key;
use Psr\Log\LoggerInterface;

/**
 * This is a proxy to crypt and decrypt password used by SiteCredential entity.
 * BTW, It might be re-use for sth else.
 */
class CryptoProxy
{
    private $logger;
    private $encryptionKey;

    public function __construct($encryptionKeyPath, LoggerInterface $logger)
    {
        $this->logger = $logger;

        if (!file_exists($encryptionKeyPath)) {
            $key = Key::createNewRandomKey();

            file_put_contents($encryptionKeyPath, $key->saveToAsciiSafeString());
            chmod($encryptionKeyPath, 0600);
        }

        $this->encryptionKey = file_get_contents($encryptionKeyPath);
    }

    /**
     * Ensure the given value will be crypted.
     *
     * @param string $secretValue Secret valye to crypt
     *
     * @return string
     */
    public function crypt($secretValue)
    {
        $this->logger->debug('Crypto: crypting value: ' . $this->mask($secretValue));

        return Crypto::encrypt($secretValue, $this->loadKey());
    }

    /**
     * Ensure the given crypted value will be decrypted.
     *
     * @param string $cryptedValue The value to be decrypted
     *
     * @return string
     */
    public function decrypt($cryptedValue)
    {
        $this->logger->debug('Crypto: decrypting value: ' . $this->mask($cryptedValue));

        try {
            return Crypto::decrypt($cryptedValue, $this->loadKey());
        } catch (WrongKeyOrModifiedCiphertextException $e) {
            throw new \RuntimeException('Decrypt fail: ' . $e->getMessage());
        }
    }

    /**
     * Load the private key.
     *
     * @return Key
     */
    private function loadKey()
    {
        return Key::loadFromAsciiSafeString($this->encryptionKey);
    }

    /**
     * Keep first and last character and put some stars in between.
     *
     * @param string $value Value to mask
     *
     * @return string
     */
    private function mask($value)
    {
        return strlen($value) > 0 ? $value[0] . '*****' . $value[strlen($value) - 1] : 'Empty value';
    }
}