我尝试使用 GCM 和 Base64 编码中的 AES 加密算法在 JS 中加密数据并在 PHP 中解密。但在解密过程中,我总是得到
false
结果,没有任何 openssl 错误。我已经验证前端和后端传输过程中的数据是相同的。我还将 "ext-openssl": "*"
添加到了我的 laravel 中的composer.json 文件中。我可能做错了什么,以至于我没有返回解密结果。
下面是我在前端用JS加密的方法
async function encryptData(data, key) {
const encoder = new TextEncoder();
const encodedData = encoder.encode(data);
// Ensure the key is 256 bits (32 bytes)
if (key.length !== 32) {
throw new Error('AES key must be 256 bits (32 bytes)');
}
const cryptoKey = await crypto.subtle.importKey('raw', new TextEncoder().encode(key), {
name: 'AES-GCM'
}, false, ['encrypt']);
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt({
name: 'AES-GCM',
iv
}, cryptoKey, encodedData);
// Concatenate IV and encrypted data and convert to base64
const combinedData = new Uint8Array(iv.length + encrypted.byteLength);
combinedData.set(iv);
combinedData.set(new Uint8Array(encrypted), iv.length);
// Convert to base64 using btoa
const base64String = btoa(String.fromCharCode.apply(null, combinedData));
return base64String; // Return the base64 string without URL encoding
}
下面是用JS在前端提交加密数据
async function submitData() {
var licence = $('#licence').val();
const encryptionKey = '12345678901234567890123456789012';
try {
let encryptedLicence = await encryptData(licence, encryptionKey);
var jsonData = {
licence: encryptedLicence
};
var queryParams = Object.keys(jsonData)
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(jsonData[key]))
.join('&');
var targetUrl = 'submit?' + queryParams;
window.location.href = targetUrl;
} catch (error) {
console.error('Error encrypting data:', error.message);
}
}
以下是我在Php中接收数据后端的方式
public function formData(Request $request){
$key = '12345678901234567890123456789012';
$data=$request->licence;
$decryptedProduct = self::decryptingMyData($data, $key);
dd($decryptedProduct);
}
下面是我如何在 Php 中解密
public function decryptingMyData($encryptedData, $key) {
// URL-decode the received data
$receivedData = urldecode($encryptedData);
$decodedData = base64_decode($receivedData);
$iv = substr($decodedData, 0, 12);
$encryptedText = substr($decodedData, 12);
$decrypted = openssl_decrypt($encryptedText, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv);
if ($decrypted === false) {
// Decryption failed
$opensslError = openssl_error_string();
dd($decrypted ,$opensslError);
return decrypted;
}
return $decrypted;
你为什么要实施这个?我认为 TLS (HTTPS) 已经涵盖了这一点。您正在使用 HTTP 吗?
const encryptionKey = '12345678901234567890123456789012';
和$key = '12345678901234567890123456789012';
是实际代码而不是示例吗?将密钥放在明文中会使加密变得毫无用处。这是不安全的。