CREATE TABLE one_time_keys (
id INT AUTO_INCREMENT PRIMARY KEY,
key_id VARCHAR(255) NOT NULL UNIQUE,
expires_at DATETIME NOT NULL,
used_at DATETIME DEFAULT NULL
);
function generateToken($secretKey) {
$end = date('Y-m-d H:i:s', strtotime('+10 minutes')); // kapan expired
$key = bin2hex(random_bytes(16)); // gunakan kode acak
$payload = base64_encode(serialize([$end, $key]));
$encrypted = openssl_encrypt($payload, 'AES-256-CBC', $secretKey, 0, substr($secretKey, 0, 16));
$hash = hash_hmac('sha256', $encrypted, $secretKey);
// Simpan ke database
$pdo = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'pass');
$stmt = $pdo->prepare("INSERT INTO one_time_keys (key_id, expires_at) VALUES (?, ?)");
$stmt->execute([$key, $end]);
return ['encrypted' => $encrypted, 'hash' => $hash];
}
function verifyToken($encrypted, $hash, $secretKey) {
$expectedHash = hash_hmac('sha256', $encrypted, $secretKey);
if (!hash_equals($expectedHash, $hash)) {
return false; // hash tidak cocok
}
$decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $secretKey, 0, substr($secretKey, 0, 16));
[$end, $key] = unserialize(base64_decode($decrypted));
if (strtotime($end) < time()) {
return false; // expired
}
// apa ada tersimpan?
$pdo = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'pass');
$stmt = $pdo->prepare("SELECT used_at FROM one_time_keys WHERE key_id = ?");
$stmt->execute([$key]);
$row = $stmt->fetch();
if (!$row || $row['used_at'] !== null) {
return false; // tidak ditemukan atau sudah dipakai
}
// sudah digunakan?
$stmt = $pdo->prepare("UPDATE one_time_keys SET used_at = NOW() WHERE key_id = ?");
$stmt->execute([$key]);
return true;
}