initial upload
This commit is contained in:
91
common.php
Normal file
91
common.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
// /var/www/html/common.php
|
||||
// Gemeinsame Helfer für Token-Validierung, Key-Derivation (HKDF) und AES (CBC, IV vorangestellt).
|
||||
|
||||
// --- MASTER-KEY (Server-seitig zum Speichern der DB) ---
|
||||
// Per ENV 'QDB_MASTER_KEY' (Base64- oder ASCII-String) oder Fallback auf bisherigen Wert.
|
||||
function get_master_key_bytes(): string {
|
||||
$env = getenv('QDB_MASTER_KEY');
|
||||
if ($env && $env !== '') {
|
||||
// Versuche Base64 zu dekodieren, sonst als ASCII nehmen
|
||||
$b = base64_decode($env, true);
|
||||
if ($b !== false && strlen($b) > 0) {
|
||||
return str_pad(substr($b, 0, 32), 32, "\0");
|
||||
}
|
||||
return str_pad(substr($env, 0, 32), 32, "\0");
|
||||
}
|
||||
// Fallback: alter Key aus bestehender Installation (32 ASCII-Bytes)
|
||||
return "12345678901234567890123456789012";
|
||||
}
|
||||
|
||||
// --- HKDF (SHA-256) über Token -> Session-Key (32 Byte) ---
|
||||
// Kompatibel zu Android-Implementierung: salt = leer, info = "qdb-aes"
|
||||
function hkdf_session_key_from_token(string $tokenHex, string $info = 'qdb-aes', int $len = 32): string {
|
||||
$ikm = @hex2bin(trim($tokenHex));
|
||||
if ($ikm === false) $ikm = $tokenHex; // Falls bereits binär
|
||||
if (function_exists('hash_hkdf')) {
|
||||
return hash_hkdf('sha256', $ikm, $len, $info, '');
|
||||
}
|
||||
// Fallback: eigene HKDF-Implementierung
|
||||
$hashLen = 32;
|
||||
$salt = str_repeat("\0", $hashLen);
|
||||
$prk = hash_hmac('sha256', $ikm, $salt, true);
|
||||
$okm = '';
|
||||
$t = '';
|
||||
$n = (int)ceil($len / $hashLen);
|
||||
for ($i = 1; $i <= $n; $i++) {
|
||||
$t = hash_hmac('sha256', $t . $info . chr($i), $prk, true);
|
||||
$okm .= $t;
|
||||
}
|
||||
return substr($okm, 0, $len);
|
||||
}
|
||||
|
||||
// --- Token-Storage (mit Ablauf) ---
|
||||
function tokens_file_path(): string {
|
||||
return __DIR__ . '/tokens.jsonl';
|
||||
}
|
||||
function token_add(string $token, int $ttlSeconds = 86400): void {
|
||||
$rec = [
|
||||
'token' => $token,
|
||||
'created' => time(),
|
||||
'exp' => time() + $ttlSeconds,
|
||||
];
|
||||
file_put_contents(tokens_file_path(), json_encode($rec) . PHP_EOL, FILE_APPEND | LOCK_EX);
|
||||
// optional weiterhin für Alt-Skripte:
|
||||
file_put_contents(__DIR__ . '/valid_tokens.txt', $token . PHP_EOL, FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
function token_is_valid(string $token): bool {
|
||||
$f = tokens_file_path();
|
||||
if (!file_exists($f)) return false;
|
||||
$h = fopen($f, 'r');
|
||||
if (!$h) return false;
|
||||
$now = time();
|
||||
$valid = false;
|
||||
while (($line = fgets($h)) !== false) {
|
||||
$j = json_decode($line, true);
|
||||
if (!is_array($j)) continue;
|
||||
if (($j['token'] ?? '') === $token && ($j['exp'] ?? 0) >= $now) {
|
||||
$valid = true; break;
|
||||
}
|
||||
}
|
||||
fclose($h);
|
||||
return $valid;
|
||||
}
|
||||
|
||||
// --- AES-256-CBC: IV(16) + CIPHERTEXT ---
|
||||
function aes256_cbc_encrypt_bytes(string $plain, string $key): string {
|
||||
$key = str_pad(substr($key, 0, 32), 32, "\0");
|
||||
$iv = random_bytes(16);
|
||||
$cipher = openssl_encrypt($plain, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
|
||||
if ($cipher === false) throw new Exception('openssl_encrypt failed');
|
||||
return $iv . $cipher;
|
||||
}
|
||||
function aes256_cbc_decrypt_bytes(string $data, string $key): string {
|
||||
if (strlen($data) < 16) throw new Exception('cipher too short');
|
||||
$key = str_pad(substr($key, 0, 32), 32, "\0");
|
||||
$iv = substr($data, 0, 16);
|
||||
$ct = substr($data, 16);
|
||||
$plain = openssl_decrypt($ct, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
|
||||
if ($plain === false) throw new Exception('openssl_decrypt failed');
|
||||
return $plain;
|
||||
}
|
||||
Reference in New Issue
Block a user