本站魅魔翻译器后端PHP源码公开
这个程序实现了一个基于密钥的文本加密与解密功能,通过接收前端 POST 请求中的操作指令(加密 / 解密)、密钥和文本,返回对应的处理结果。
以下为具体的源代码:
<?php
class CipherServer {
private function generate_maps($key) {
$chars = [‘哦’, ‘齁’, ‘❤’, ‘咿’, ‘啊’, ‘呃’,’~’, ‘!’];
$hash = hash(‘sha256’, $key);
$seed = hexdec(substr($hash, 0, 8));
// 使用确定性洗牌替代mt_rand
$shuffled = $chars;
$count = count($shuffled);
$state = $seed;
for ($i = $count – 1; $i > 0; $i–) {
// 生成确定性随机索引
$state = crc32($hash . $state) & 0xFFFFFFFF;
$j = $state % ($i + 1);
// 交换元素
[$shuffled[$i], $shuffled[$j]] = [$shuffled[$j], $shuffled[$i]];
}
$binary_map = [
‘000’ => $shuffled[0],
‘001’ => $shuffled[1],
‘010’ => $shuffled[2],
‘011’ => $shuffled[3],
‘100’ => $shuffled[4],
‘101’ => $shuffled[5],
‘110’ => $shuffled[6],
‘111’ => $shuffled[7]
];
$text_map = array_flip($binary_map);
return [$binary_map, $text_map];
}
private function generateKeyStream($length, $key) {
$stream = ”;
$hash = $key;
while (strlen($stream) < $length) {
$hash = hash(‘sha256’, $hash, true);
$stream .= $hash;
}
return substr($stream, 0, $length);
}
public function encrypt_text($text, $key) {
if (!preg_match(‘/^[\x21-\x7E]{1,20}$/’, $key)) {
return [‘error’ => ‘密钥格式错误,必须为1-20位可打印ASCII字符(除空格外)’];
}
$keyStream = $this->generateKeyStream(strlen($text), $key);
[$binary_map] = $this->generate_maps($key);
$bytes = unpack(‘C*’, $text);
$keyBytes = unpack(‘C*’, $keyStream);
$binary = ”;
for ($i = 1; $i <= count($bytes); $i++) {
$xorByte = $bytes[$i] ^ $keyBytes[$i];
$binary .= str_pad(decbin($xorByte), 8, ‘0’, STR_PAD_LEFT);
}
$padLength = (3 – (strlen($binary) % 3)) % 3;
$binary .= str_repeat(‘0’, $padLength);
$result = ”;
for ($i = 0; $i < strlen($binary); $i += 3) {
$bits = substr($binary, $i, 3);
$result .= $binary_map[$bits];
}
return [‘result’ => $result];
}
public function decrypt_text($cipher, $key) {
if (!preg_match(‘/^[\x21-\x7E]{1,20}$/’, $key)) {
return [‘error’ => ‘密钥格式错误,必须为1-20位可打印ASCII字符(除空格外)’];
}
[, $text_map] = $this->generate_maps($key);
$binary = ”;
preg_match_all(‘/./u’, $cipher, $matches);
foreach ($matches[0] as $char) {
if (!isset($text_map[$char])) {
return [‘error’ => ‘包含无效字符’];
}
$binary .= $text_map[$char];
}
$originalLength = floor(strlen($binary) * 3 / 8) * 8;
$binary = substr($binary, 0, $originalLength);
$byteLength = strlen($binary) / 8;
$keyStream = $this->generateKeyStream($byteLength, $key);
$text = ”;
for ($i = 0; $i < $byteLength; $i++) {
$byteBin = substr($binary, $i * 8, 8);
$cipherByte = bindec($byteBin);
$keyByte = ord($keyStream[$i]);
$text .= chr($cipherByte ^ $keyByte);
}
return [‘result’ => $text];
}
}
header(‘Content-Type: application/json’);
$action = $_POST[‘action’] ?? ”;
$key = $_POST[‘key’] ?? ”;
$text = $_POST[‘text’] ?? ”;
$cipher = new CipherServer();
if ($action === ‘encrypt’) {
echo json_encode($cipher->encrypt_text($text, $key));
} elseif ($action === ‘decrypt’) {
echo json_encode($cipher->decrypt_text($text, $key));
} else {
echo json_encode([‘error’ => ‘无效的操作’]);
}
?>
有趣的是,我还做了一个使用AES256和RSA4096的加密方法,这个方法可以说在不泄露密钥的情况下,做到了几乎无法破译,但是由于密文长度是明文的几乎700倍,已经不适合日常娱乐使用了,所以网站不使用这一版,作为一个整活项目挺合适的。
以下为plus版的源代码:
<?php
class CipherServer {
private $rsa_private_key;
private $rsa_public_key;
// 构造函数:从文件加载密钥,密钥需要自己生成,长度4096,格式PKCS8,生成完之后下载,
// 公钥命名public_key.pem,私钥命名private_key.pem,均上传到服务器里,和本文件同目录,服务器PHP版本推荐8.0+,需要启用openssl
public function __construct() {
$this->rsa_private_key = file_get_contents(‘private_key.pem’);
$this->rsa_public_key = file_get_contents(‘public_key.pem’);
if (!$this->rsa_private_key || !$this->rsa_public_key) {
throw new Exception(“无法加载RSA密钥文件”);
}
}
private function generate_maps($key) {
$chars = [‘哦’, ‘齁’, ‘❤’, ‘咿’, ‘啊’, ‘呃’,’~’, ‘!’];
$hash = hash(‘sha256’, $key);
$seed = hexdec(substr($hash, 0, 8));
$shuffled = $chars;
$count = count($shuffled);
$state = $seed;
for ($i = $count – 1; $i > 0; $i–) {
$state = crc32($hash . $state) & 0xFFFFFFFF;
$j = $state % ($i + 1);
[$shuffled[$i], $shuffled[$j]] = [$shuffled[$j], $shuffled[$i]];
}
$binary_map = [
‘000’ => $shuffled[0],
‘001’ => $shuffled[1],
‘010’ => $shuffled[2],
‘011’ => $shuffled[3],
‘100’ => $shuffled[4],
‘101’ => $shuffled[5],
‘110’ => $shuffled[6],
‘111’ => $shuffled[7]
];
$text_map = array_flip($binary_map);
return [$binary_map, $text_map];
}
private function generateKeyStream($length, $key) {
$stream = ”;
$hash = $key;
while (strlen($stream) < $length) {
$hash = hash(‘sha256’, $hash, true);
$stream .= $hash;
}
return substr($stream, 0, $length);
}
public function encrypt_text($text, $key) {
if (!preg_match(‘/^[\x21-\x7E]{1,20}$/’, $key)) {
return [‘error’ => ‘密钥格式错误’];
}
$aes_key = openssl_random_pseudo_bytes(32);
$iv = openssl_random_pseudo_bytes(16);
$aes_encrypted = openssl_encrypt(
$text,
‘aes-256-cbc’,
$aes_key,
OPENSSL_RAW_DATA,
$iv
);
if ($aes_encrypted === false) {
return [‘error’ => ‘AES加密失败: ‘ . openssl_error_string()];
}
$key_iv = $aes_key . $iv;
$rsa_success = openssl_public_encrypt(
$key_iv,
$encrypted_key_iv,
$this->rsa_public_key
);
if (!$rsa_success) {
return [‘error’ => ‘RSA加密失败: ‘ . openssl_error_string()];
}
$combined_binary = $encrypted_key_iv . $aes_encrypted;
[$binary_map] = $this->generate_maps($key);
$keyStream = $this->generateKeyStream(strlen($combined_binary), $key);
$bytes = unpack(‘C*’, $combined_binary);
$keyBytes = unpack(‘C*’, $keyStream);
$binary = ”;
for ($i = 1; $i <= count($bytes); $i++) {
$binary .= str_pad(decbin($bytes[$i] ^ $keyBytes[$i]), 8, ‘0’, STR_PAD_LEFT);
}
$padLength = (3 – (strlen($binary) % 3)) % 3;
$binary .= str_repeat(‘0’, $padLength);
$result = ”;
for ($i = 0; $i < strlen($binary); $i += 3) {
$result .= $binary_map[substr($binary, $i, 3)];
}
return [‘result’ => $result];
}
public function decrypt_text($cipher, $key) {
if (!preg_match(‘/^[\x21-\x7E]{1,20}$/’, $key)) {
return [‘error’ => ‘密钥格式错误’];
}
[, $text_map] = $this->generate_maps($key);
$binary = ”;
preg_match_all(‘/./u’, $cipher, $matches);
foreach ($matches[0] as $char) {
if (!isset($text_map[$char])) {
return [‘error’ => ‘无效的密文字符’];
}
$binary .= $text_map[$char];
}
$originalLength = floor(strlen($binary) * 3 / 8) * 8;
$binary = substr($binary, 0, $originalLength);
$byteLength = strlen($binary) / 8;
$keyStream = $this->generateKeyStream($byteLength, $key);
$combined_binary = ”;
for ($i = 0; $i < $byteLength; $i++) {
$byte = bindec(substr($binary, $i*8, 8));
$combined_binary .= chr($byte ^ ord($keyStream[$i]));
}
$rsa_block_size = 512;
if (strlen($combined_binary) < $rsa_block_size) {
return [‘error’ => ‘密文长度不足’];
}
$encrypted_key_iv = substr($combined_binary, 0, $rsa_block_size);
$aes_encrypted = substr($combined_binary, $rsa_block_size);
$rsa_success = openssl_private_decrypt(
$encrypted_key_iv,
$decrypted_key_iv,
$this->rsa_private_key
);
if (!$rsa_success || strlen($decrypted_key_iv) !== 48) {
return [‘error’ => ‘RSA解密失败: ‘ . openssl_error_string()];
}
$aes_key = substr($decrypted_key_iv, 0, 32);
$iv = substr($decrypted_key_iv, 32, 16);
$text = openssl_decrypt(
$aes_encrypted,
‘aes-256-cbc’,
$aes_key,
OPENSSL_RAW_DATA,
$iv
);
if ($text === false) {
return [‘error’ => ‘AES解密失败: ‘ . openssl_error_string()];
}
return [‘result’ => $text];
}
}
header(‘Content-Type: application/json’);
$action = $_POST[‘action’] ?? ”;
$key = $_POST[‘key’] ?? ”;
$text = $_POST[‘text’] ?? ”;
try {
$cipher = new CipherServer();
if ($action === ‘encrypt’) {
echo json_encode($cipher->encrypt_text($text, $key));
} elseif ($action === ‘decrypt’) {
echo json_encode($cipher->decrypt_text($text, $key));
} else {
echo json_encode([‘error’ => ‘无效的操作’]);
}
} catch (Exception $e) {
echo json_encode([‘error’ => ‘服务器错误: ‘ . $e->getMessage()]);
}
?>
评论(0)
暂无评论