在 JS 中加密,在 PHP 中解密,使用 GCM 中的 AES 加密算法和 Base64 编码

问题描述 投票:0回答:1

我尝试使用 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;                                                                                                                                    
javascript cryptoapi php-8 php-openssl
1个回答
1
投票

你为什么要实施这个?我认为 TLS (HTTPS) 已经涵盖了这一点。您正在使用 HTTP 吗?

const encryptionKey = '12345678901234567890123456789012';
$key = '12345678901234567890123456789012';
是实际代码而不是示例吗?将密钥放在明文中会使加密变得毫无用处。这是不安全的。

© www.soinside.com 2019 - 2024. All rights reserved.