php RSA encryption and decryption

php RSA encryption and decryption

Related introduction

RSA algorithm belongs to asymmetric encryption algorithm, which requires two secret keys: public key and private key The public key and private key are a pair,

If the public key encrypts the data, it can only be decrypted with the corresponding private key;

If the private key encrypts the data, it can only be decrypted with the corresponding public key

Because encryption and decryption use two different secret keys, this algorithm is called asymmetric encryption algorithm In short, public key encryption, private key decryption, private key encryption and public key decryption

Points needing attention

1. The result of RSA encryption or signature is unreadable binary, which is often converted to BASE64 code and then transmitted

2. During RSA encryption, the size of the data to be encrypted is limited, and the maximum length is not greater than the key length. For example, when using a 1024 bit key (the secret key can be generated by Baidu itself), the maximum data of 1024/8=128 Bytes can be encrypted. When the data is greater than 128 Bytes, the data needs to be encrypted in groups (if the data exceeds the limit, the encryption and decryption will fail, and the openssl function will return false). The encrypted string after group encryption is spliced into a string and sent to the client.

In order to ensure that the results of each encryption are different, RSA encryption will splice a random string after the data to be encrypted, and then encrypt it. Different padding means different lengths of this string. After grouping the out of limit data, the random string will be filled according to the length specified by this padding. For example, if the padding filling method uses the default OPENSSL_PKCS1_PADDING (11 bytes are required for filling), the plaintext length can only be 128-11=117 Bytes at most.

The receiver also needs grouping when decrypting. The encrypted original binary data (for the data passing BASE64, it needs to be decoded) is divided into a group every 128 Bytes, and then decrypted. After decryption, discard the random string according to the length of Padding, and splice the obtained original string to obtain the original message.

3.openssl_ public_ There is a difference between the default filling and no filling of the encrypt function php. If only php and php are connected, you don't need to pay attention to this problem. If php is connected with c or java, you need to select no filling and then add filling by yourself

4. You need to open or install the openssl module of php (open on win, install on linux, Baidu)

For my convenience, I provide a set of 1024 bit public-private key signatures:

 

/*********************Test public key*******************************
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmkANmC849IOntYQQdSgLvMMGm
8V/u838ATHaoZwvweoYyd+/7Wx+bx5bdktJb46YbqS1vz3VRdXsyJIWhpNcmtKhY
inwcl83aLtzJeKsznppqMyAIseaKIeAm6tT8uttNkr2zOymL/PbMpByTQeEFlyy1
poLBwrol0F4USc+owwIDAQAB
-----END PUBLIC KEY-----
*************************************************************
************************Test private key*****************************
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKaQA2YLzj0g6e1h
BB1KAu8wwabxX+7zfwBMdqhnC/B6hjJ37/tbH5vHlt2S0lvjphupLW/PdVF1ezIk
haGk1ya0qFiKfByXzdou3Ml4qzOemmozIAix5ooh4Cbq1Py6202SvbM7KYv89syk
HJNB4QWXLLWmgsHCuiXQXhRJz6jDAgMBAAECgYAIF5cSriAm+CJlVgFNKvtZg5Tk
93UhttLEwPJC3D7IQCuk6A7Qt2yhtOCvgyKVNEotrdp3RCz++CY0GXIkmE2bj7i0
fv5vT3kWvO9nImGhTBH6QlFDxc9+p3ukwsonnCshkSV9gmH5NB/yFoH1m8tck2Gm
BXDj+bBGUoKGWtQ7gQJBANR/jd5ZKf6unLsgpFUS/kNBgUa+EhVg2tfr9OMioWDv
MSqzG/sARQ2AbO00ytpkbAKxxKkObPYsn47MWsf5970CQQDIqRiGmCY5QDAaejW4
HbOcsSovoxTqu1scGc3Qd6GYvLHujKDoubZdXCVOYQUMEnCD5j7kdNxPbVzdzXll
9+p/AkEAu/34iXwCbgEWQWp4V5dNAD0kXGxs3SLpmNpztLn/YR1bNvZry5wKew5h
z1zEFX+AGsYgQJu1g/goVJGvwnj/VQJAOe6f9xPsTTEb8jkAU2S323BG1rQFsPNg
jY9hnWM8k2U/FbkiJ66eWPvmhWd7Vo3oUBxkYf7fMEtJuXu+JdNarwJAAwJK0YmO
LxP4U+gTrj7y/j/feArDqBukSngcDFnAKu1hsc68FJ/vT5iOC6S7YpRJkp8egj5o
pCcWaTO3GgC5Kg==
-----END PRIVATE KEY-----

The following describes the related functions used:

openssl_pkey_get_public() extracts the public key from the certificate
openssl_pkey_get_private() Extract private key from certificate
openssl_public_encrypt() Public key encryption
openssl_private_decrypt() Private key decryption
openssl_private_encrypt() Private key encryption
openssl_public_decrypt() Public key decryption
base64_encode() Recoding data using Base64
base64_decode() Decode Base64 data

All right, that's the end of the preparations. The following is the specific coding:

Step 1: define the public-private key signature as a constant

 
define('RSA_PUBLIC', '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmkANmC849IOntYQQdSgLvMMGm
8V/u838ATHaoZwvweoYyd+/7Wx+bx5bdktJb46YbqS1vz3VRdXsyJIWhpNcmtKhY
inwcl83aLtzJeKsznppqMyAIseaKIeAm6tT8uttNkr2zOymL/PbMpByTQeEFlyy1
poLBwrol0F4USc+owwIDAQAB
-----END PUBLIC KEY-----');

define('RSA_PRIVATE','-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKaQA2YLzj0g6e1h
BB1KAu8wwabxX+7zfwBMdqhnC/B6hjJ37/tbH5vHlt2S0lvjphupLW/PdVF1ezIk
haGk1ya0qFiKfByXzdou3Ml4qzOemmozIAix5ooh4Cbq1Py6202SvbM7KYv89syk
HJNB4QWXLLWmgsHCuiXQXhRJz6jDAgMBAAECgYAIF5cSriAm+CJlVgFNKvtZg5Tk
93UhttLEwPJC3D7IQCuk6A7Qt2yhtOCvgyKVNEotrdp3RCz++CY0GXIkmE2bj7i0
fv5vT3kWvO9nImGhTBH6QlFDxc9+p3ukwsonnCshkSV9gmH5NB/yFoH1m8tck2Gm
BXDj+bBGUoKGWtQ7gQJBANR/jd5ZKf6unLsgpFUS/kNBgUa+EhVg2tfr9OMioWDv
MSqzG/sARQ2AbO00ytpkbAKxxKkObPYsn47MWsf5970CQQDIqRiGmCY5QDAaejW4
HbOcsSovoxTqu1scGc3Qd6GYvLHujKDoubZdXCVOYQUMEnCD5j7kdNxPbVzdzXll
9+p/AkEAu/34iXwCbgEWQWp4V5dNAD0kXGxs3SLpmNpztLn/YR1bNvZry5wKew5h
z1zEFX+AGsYgQJu1g/goVJGvwnj/VQJAOe6f9xPsTTEb8jkAU2S323BG1rQFsPNg
jY9hnWM8k2U/FbkiJ66eWPvmhWd7Vo3oUBxkYf7fMEtJuXu+JdNarwJAAwJK0YmO
LxP4U+gTrj7y/j/feArDqBukSngcDFnAKu1hsc68FJ/vT5iOC6S7YpRJkp8egj5o
pCcWaTO3GgC5Kg==
-----END PRIVATE KEY-----');

Step 2: perform public key encryption

 
//Public key encryption 
$public_key = openssl_pkey_get_public(RSA_PUBLIC); 
if(!$public_key){
    die('Public key not available');
}
//The first parameter is that the data to be encrypted can only be string, the second parameter is the encrypted data, and the third parameter is OpenSSL_ pkey_ get_ The fourth parameter of the resource type returned by public is the filling method
$return_en = openssl_public_encrypt("hello world", $crypted, $public_key);
if(!$return_en){
    return('Encryption failed,Please check RSA Secret key');
}
$eb64_cry = base64_encode($crypted);
echo "Public key encrypted data:".$eb64_cry;
echo "<hr>";

Step 3: Test decryption using private key

 
//Private key decryption
$private_key = openssl_pkey_get_private(RSA_PRIVATE);
if(!$private_key){
    die('Private key not available');
}
$return_de = openssl_private_decrypt(base64_decode($eb64_cry), $decrypted, $private_key);
if(!$return_de){
    return('Decryption failed,Please check RSA Secret key');
}
echo "Decrypt data with private key:".$decrypted;
echo "<hr>";

Run and you can see the results:

Private key encryption and public key decryption:

 
//Private key encryption
$private_key = openssl_pkey_get_private(RSA_PRIVATE);
if(!$private_key){
    die('Private key not available');
}
$return_en = openssl_private_encrypt("hello world222222", $crypted, $private_key);
if(!$return_en){
    return('Encryption failed,Please check RSA Secret key');
}
$eb64_cry = base64_encode($crypted);
echo "Private key encrypts data".$eb64_cry;
echo "<hr>";

//Public key decryption
$public_key = openssl_pkey_get_public(RSA_PUBLIC);
if(!$public_key){
    die('Public key not available');
}
$return_de = openssl_public_decrypt(base64_decode($eb64_cry), $decrypted, $public_key);
if(!$return_de){
    return('Decryption failed,Please check RSA Secret key');
}
echo "Public key decryption data:".$decrypted;
echo "<hr>";

Run and you can see the results:

The above is the encryption and decryption using php's default filling method. Please know

Posted by foyer on Mon, 09 May 2022 11:40:16 +0300