summaryrefslogtreecommitdiff
path: root/lib/nextpage.php
blob: a883e499d71bbf6594d0fb1a777fab0ff5d75923 (plain)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php

class nextpage{
	
	public function __construct($scraper){
		
		$this->scraper = $scraper;
	}
	
	public function store($payload, $page){
		
		$page = $page[0];
		$password = random_bytes(256); // 2048 bit
		$salt = random_bytes(16);
		$key = hash_pbkdf2("sha512", $password, $salt, 20000, 32, true);
		$iv =
			random_bytes(
				openssl_cipher_iv_length("aes-256-gcm")
			);
		
		$tag = "";
		$out = openssl_encrypt($payload, "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag, "", 16);
		
		$key = apcu_inc("key", 1);

		apcu_store(
			$page . "." .
			$this->scraper .
			(string)($key),
			gzdeflate($salt.$iv.$out.$tag),
			420 // cache information for 7 minutes blaze it
		);

		return 
			$this->scraper . $key . "." .
			rtrim(strtr(base64_encode($password), '+/', '-_'), '=');
	}
	
	public function get($npt, $page){
		
		$page = $page[0];
		$explode = explode(".", $npt, 2);
		
		if(count($explode) !== 2){
			
			throw new Exception("Malformed nextPageToken!");
		}
		
		$apcu = $page . "." . $explode[0];
		$key = $explode[1];
		
		$payload = apcu_fetch($apcu);
		
		if($payload === false){
			
			throw new Exception("The nextPageToken is invalid or has expired!");
		}
		
		$key =
			base64_decode(
				str_pad(
					strtr($key, '-_', '+/'),
					strlen($key) % 4,
					'=',
					STR_PAD_RIGHT
				)
			);
		
		$payload = gzinflate($payload);
		
		$key =
			hash_pbkdf2(
				"sha512",
				$key,
				substr($payload, 0, 16), // salt
				20000,
				32,
				true
			);
		$ivlen = openssl_cipher_iv_length("aes-256-gcm");
		
		$payload =
			openssl_decrypt(
				substr(
					$payload,
					16 + $ivlen,
					-16
				),
				"aes-256-gcm",
				$key,
				OPENSSL_RAW_DATA,
				substr($payload, 16, $ivlen),
				substr($payload, -16)
			);
		
		if($payload === false){
			
			throw new Exception("The nextPageToken is invalid or has expired!");
		}
		
		// remove the key after using
		apcu_delete($apcu);
		
		return $payload;
	}
}