Criptografia e descriptografia PHP RSA2 e assinatura e verificação de interface

Está em desenvolvimento? Muitas vezes temos que lidar com interfaces, seja para chamar a interface de outra pessoa ou fornecer uma interface a outra pessoa, como garantir a segurança e a consistência dos dados de ambas as partes quando a interface é chamada? Isso envolve criptografia de dados e serviços de verificação de assinatura. Este artigo usa exemplos de PHP para explicar a implementação das funções de criptografia e descriptografia de dados RSA2 e verificação de assinatura.

No artigo anterior " Quais são os métodos de criptografia comuns no desenvolvimento WEB ", apresentamos o algoritmo de criptografia assimétrica RSA2, que é adequado para criptografar uma pequena quantidade de dados, como dados de pagamento e outros cenários com altos requisitos de segurança.

Primeiro, precisamos gerar arquivos de chave pública e privada:

openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem

Criptografia RSA2

Presumimos que as informações de pagamento do usuário precisam ser criptografadas e enviadas ao sistema de pagamento back-end por meio da interface. O cliente usuário usa a chave pública para criptografar os dados e o sistema de pagamento back-end usa a chave privada para descriptografar os dados.

$publicKey = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRJ6it8Vnl3BUfJok8JYPMkAra
vmjj/cUElcBgp9Ez4hw9rzloqszOye1cyYdkH9EJhp55wwhZl2B6Mx7kahu08wJn
h90j0IVArKUYau9u2hOQ52+VvEAbTYh8LkWfN1gvtcquSVwqKRjmBApo1LTpOooD
FrLRji8oiE7bLXHNgQIDAQAB
-----END PUBLIC KEY-----';

//需要加密的数据
$data = [
    'order_id' => 'N2020020212345689232',
    'money' => 1000000,
    'user_id' => 1982,
    'pay_type' => 'alipay',
    'pay_time' => 1583213421
];

$publicKey = openssl_pkey_get_public($publicKey); //解析公钥
$rs = openssl_public_encrypt(json_encode($data), $encrypted, $publicKey) ? base64_encode($encrypted) : null; 
echo $rs;

Podemos copiar e colar a chave pública gerada diretamente no arquivo de código ou usar fopen()Abrir para ler o arquivo de chave pública. Observe que o openssl_public_encrypt()conteúdo de texto simples criptografado não pode ser muito longo. Para conteúdo muito longo, considere a criptografia de segmentação ou use a criptografia DES.

Após a execução, obtenha o conteúdo criptografado:

A7yj2Yjuc4Y8jhtmz5MdxrMFGhyortBJ53kYQZ8MMNNsjW2rW21a/l4DH247xh0zkPPHHzygGqNIFwuiPFaK2RvubfjZxyqIfNts8RkNXGSTIYCKv6BobI3AWcgF+eyyrhaoTiiCUVwDqNrVoLVZdOPReyK5dOvOPd1nXemhg9Q=

Descriptografia RSA2

Depois que o sistema de pagamento back-end recebe o conteúdo criptografado, ele usa a chave privada para descriptografá-lo.

$privateKey = '-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANEnqK3xWeXcFR8m
iTwlg8yQCtq+aOP9xQSVwGCn0TPiHD2vOWiqzM7J7VzJh2Qf0QmGnnnDCFmXYHoz
HuRqG7TzAmeH3SPQhUCspRhq727aE5Dnb5W8QBtNiHwuRZ83WC+1yq5JXCopGOYE
CmjUtOk6igMWstGOLyiITtstcc2BAgMBAAECgYBmCrlLE+NON8++QOjXhV4GIYiK
LDe0dAz5La6L+ZQhggFRPvn9TMdbZDz/9fquKK+tvBX5ReP/AdG6DNLXkcUt4yuG
JomQ0qiUw8e2J5xglb0lfgMvFJAUAnBRr8bOwg6YrUcRI9PiXM/bwOnjjX9eA/Ox
Bf7rmvQtfvSWqpEqgQJBAO++2sCInm8Mdy/RrN9A8CLx2Utzbb5e3K5i6Qr3H3As
++Gxx6RVhKhBoF2Kpy2abQclFnzuURH2d8Smun9yDjkCQQDfVdu0zi1OsX5mUuJa
AUfali+eF+HK7uYte9oTJULn1ykJaBkUFYFK08bWURc/SKN4WT4wf537clFVbCl2
KbmJAkEAjR8KAwUoRXPQAJzqpmvCLr+vycMDWWjbe+cLCIJYxh4kkkCkpK4WLTic
HhPMvoJFJUyGhTl/DRTIgUAnTXekuQJAP3FLZVRAaJ9hMb4P0NOWTtDlG/rayGQO
/RK2w0ONewCTBroMjbkCLnh0foMwoGiJD3ICiZJnFXvHAQYlzQxTSQJAFHFi5UmT
99AX8DZ7gRnjFqrzjkEMIY2klKv26x6fSGcoQ7pYhbnj4S9pmUMthfdACWp9kTkW
w5gQhVfGr8dOXA==
-----END PRIVATE KEY-----';

$key = openssl_pkey_get_private($privateKey); //解析私钥
$encrypted = base64_decode($encrypted);
//解密
$mydata = openssl_private_decrypt($encrypted, $decrypted, $key) ? $decrypted : null;
echo $mydata;

Após a execução, obtenha os dados descriptografados:

{"order_id":"N2020020212345689232","money":1000000,"user_id":1982,"pay_type":"alipay","pay_time":1583213421}

Assinatura RSA2

Em primeiro lugar, precisamos entender por que precisamos assinar? Quando estamos fazendo solicitações de dados, para evitar que os dados sejam interceptados ou adulterados, causando efeitos negativos, precisamos realizar a verificação de assinatura ao enviar e receber dados através da interface de dados. O princípio da assinatura é: o cliente e o servidor usam o mesmo algoritmo de assinatura para calcular a assinatura.Quando a assinatura enviada pelo cliente é consistente com a assinatura fornecida pelo servidor, a assinatura é bem-sucedida.

Usamos RSA2 para assinar dados do cliente. Observe que a parte assinante usa a chave privada para provar que a assinatura foi enviada do seu cliente. Obviamente, a parte de verificação é o servidor que usa a chave pública para verificar a assinatura. No exemplo a seguir, ainda usamos as chaves públicas e privadas geradas no início do artigo.

//要签名的数据
$data = [
    'order_id' => 'N2020020212345689232',
    'money' => 1000000,
    'user_id' => 1982,
    'pay_type' => 'alipay',
    'pay_time' => 1583213421
];

$privateKey = openssl_pkey_get_private($privateKey);
$signature = openssl_sign(json_encode($data), $sign, $privateKey, OPENSSL_ALGO_SHA256) ? base64_encode($sign) : null;
echo $signature;

A função openssl_sign()assina os dados de pagamento com RS2 e obtém a assinatura após executar:

eYg6ss/iOuie8SUikqdTTBmctOatTV+zrw5NGfR33rPJvzSrRRZvC/ynwaS3ZLoX4sUlD0mcF9WEoLwG1IXKeqszkCkY06DejvUZNk4N5Ie49MiBPOgTz2qdWP1Q0bnL2T7c+KqDLn9tk2vzDRUoMW8aPPXuJFiNTYaNf50aty0=

Verificação RSA2

Depois que o servidor recebe os dados e a assinatura enviados pelo cliente, ele usa a chave pública para verificar a assinatura.

//接收客户端的签名
$sign = 'eYg6ss/iOuie8SUikqdTTBmctOatTV+zrw5NGfR33rPJvzSrRRZvC/ynwaS3ZLoX4sUlD0mcF9WEoLwG1IXKeqszkCkY06DejvUZNk4N5Ie49MiBPOgTz2qdWP1Q0bnL2T7c+KqDLn9tk2vzDRUoMW8aPPXuJFiNTYaNf50aty0=';
//接收客户端的原始数据
$data = [
    'order_id' => 'N2020020212345689232',
    'money' => 1000000,
    'user_id' => 1982,
    'pay_type' => 'alipay',
    'pay_time' => 1583213421
];

$publicKey = openssl_pkey_get_public($publicKey);
$rs = openssl_verify(json_encode($data), base64_decode($sign), $publicKey, OPENSSL_ALGO_SHA256);
var_dump($rs);
if ($rs) {
    echo 'ok';
    ...do something...
} else {
    echo 'fail...';
}

No código acima, a fim de demonstrar a atribuição de duas variáveis para $signe $data, de fato, esses dois valores são passados ​​do cliente, geralmente postsubmetidos, aqui não é uma demonstração no código, você pode praticar por si mesmo.

Depois de executar o código acima, "ok" é gerado com sucesso, ou seja, a verificação foi bem-sucedida.

o de cima.

 

Este artigo vem de: helloweba.net

Link original: https://www.helloweba.net/php/630.html

Acho que você gosta

Origin blog.csdn.net/z3287852/article/details/113421794
Recomendado
Clasificación