如何用PHP/JavaScript隐藏URL?求Apache/PHP URL加密实现方案
Hey there! Let's break down how to achieve this URL obfuscation/encryption you're asking about—turning a readable URL like www.example.com/how-to-encrypt.html into that jumbled string www.example.com/DMQRzZWMDdGQtbndzBHNsawN0aXRsZQR0ZXN0AzcwMQR3b2UDMjQwMjEwNQ.
First off: this requires a combination of PHP (for encryption/decryption logic) and Apache (for URL rewriting). JavaScript can help generate encrypted links on the frontend, but never rely on it for core security—since client-side code is always visible to users.
Here's a step-by-step implementation:
1. PHP Encryption/Decryption Functions
We'll use OpenSSL (built into PHP) for secure reversible encryption. This ensures we can turn a path into that random string, and turn it back later to load the correct content.
<?php // Use a long, random secret key (generate one with `openssl rand -hex 16` in terminal) define('URL_ENCRYPT_KEY', 'your-32-character-secret-key-here'); // Encrypt a URL path into the obfuscated string function encryptUrlPath($path) { $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc')); $encrypted = openssl_encrypt($path, 'aes-256-cbc', URL_ENCRYPT_KEY, 0, $iv); // Replace Base64 special chars to avoid URL issues return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($iv . $encrypted)); } // Decrypt the obfuscated string back to the original path function decryptUrlPath($encryptedStr) { // Restore Base64 characters $encryptedStr = str_replace(['-', '_'], ['+', '/'], $encryptedStr); $decoded = base64_decode($encryptedStr); $ivLength = openssl_cipher_iv_length('aes-256-cbc'); $iv = substr($decoded, 0, $ivLength); $encryptedContent = substr($decoded, $ivLength); return openssl_decrypt($encryptedContent, 'aes-256-cbc', URL_ENCRYPT_KEY, 0, $iv); } ?>
2. Generate Encrypted Links
In your PHP pages, use the encryptUrlPath function to create clickable encrypted links:
<?php $originalPath = '/how-to-encrypt.html'; $encryptedPath = encryptUrlPath($originalPath); ?> <a href="/<?= $encryptedPath ?>">Go to Encrypted Page</a>
3. Apache Rewrite Rules (.htaccess)
We need to route all requests for encrypted strings to a central router script. Create a .htaccess file in your site root:
RewriteEngine On # Skip real files/directories (like CSS, JS, images) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # Forward all other requests to router.php with the encrypted string as a parameter RewriteRule ^(.*)$ router.php?code=$1 [L,QSA]
4. Router Script (router.php)
This script decrypts the string, validates the path, and loads the correct content:
<?php require 'path/to/your/encryption-functions.php'; if (isset($_GET['code'])) { $encryptedStr = $_GET['code']; $originalPath = decryptUrlPath($encryptedStr); // Critical: Prevent directory traversal attacks $siteRoot = realpath($_SERVER['DOCUMENT_ROOT']); $targetFile = realpath($siteRoot . $originalPath); if ($targetFile && strpos($targetFile, $siteRoot) === 0 && file_exists($targetFile)) { // Load the requested page include $targetFile; exit; } else { // Invalid path, return 404 header("HTTP/1.0 404 Not Found"); echo "404 - Page not found"; exit; } } // Redirect to homepage if no code is provided header("Location: /"); exit; ?>
Optional: Using JavaScript for Frontend Link Generation
If you want to generate encrypted links client-side, don't put encryption logic in JS (it's insecure). Instead, fetch the encrypted path from a PHP endpoint:
// Frontend JS fetch('/api/get-encrypted-path.php?path=/how-to-encrypt.html') .then(res => res.text()) .then(encryptedPath => { const link = document.createElement('a'); link.href = `/${encryptedPath}`; link.textContent = 'Encrypted Link'; document.body.appendChild(link); });
And the corresponding api/get-encrypted-path.php:
<?php require '../path/to/your/encryption-functions.php'; if (isset($_GET['path'])) { $path = $_GET['path']; $siteRoot = realpath($_SERVER['DOCUMENT_ROOT']); $targetFile = realpath($siteRoot . $path); // Only return encrypted path if it's a valid file in the site root if ($targetFile && strpos($targetFile, $siteRoot) === 0) { echo encryptUrlPath($path); } else { echo ''; } } ?>
Key Notes
- Secret Key: Never hardcode a weak key! Generate a random 32-character string for AES-256.
- Security: This is URL obfuscation/encryption, not perfect hiding. Anyone with access to your server code or key can decrypt it, but it's enough to block casual URL guessing.
- Database Alternative: For higher security, you could map encrypted strings to paths in a database (no reversible encryption needed)—but this adds maintenance overhead.
内容的提问来源于stack exchange,提问作者Mike P

