Шифрование и расшифровка текста с помощью RSA на PHP
Существует ли какой-либо класс для PHP 5.3, который обеспечит шифрование/дешифрование текста с помощью RSA без заполнения?
У меня есть закрытый и открытый ключи, p, q и модуль.
4 answers
Вы можете использовать phpseclib, чистую реализацию PHP RSA:
<?php
include('Crypt/RSA.php');
$privatekey = file_get_contents('private.key');
$rsa = new Crypt_RSA();
$rsa->loadKey($privatekey);
$plaintext = new Math_BigInteger('aaaaaa');
echo $rsa->_exponentiate($plaintext)->toBytes();
?>
class MyEncryption
{
public $pubkey = '...public key here...';
public $privkey = '...private key here...';
public function encrypt($data)
{
if (openssl_public_encrypt($data, $encrypted, $this->pubkey))
$data = base64_encode($encrypted);
else
throw new Exception('Unable to encrypt data. Perhaps it is bigger than the key size?');
return $data;
}
public function decrypt($data)
{
if (openssl_private_decrypt(base64_decode($data), $decrypted, $this->privkey))
$data = $decrypted;
else
$data = '';
return $data;
}
}
Ни одно приложение, написанное в 2017 году (или после этого), которое намерено включить серьезную криптографию, больше не должно использовать RSA. Существуют лучшие варианты криптографии с открытым ключом PHP.
Есть две большие ошибки, которые люди совершают, когда решают зашифровать с помощью RSA:
- Разработчики выбрали неправильный режим заполнения.
- Поскольку RSA сам по себе не может шифровать очень длинные строки, разработчики часто разбивают строку на небольшие фрагменты и зашифруйте каждый фрагмент независимо. Что-то вроде режима ЕЦБ.
Лучшая альтернатива: sodium_crypto_box_seal()
(либсодиум)
$keypair = sodium_crypto_box_keypair();
$publicKey = sodium_crypto_box_publickey($keypair);
// ...
$encrypted = sodium_crypto_box_seal(
$plaintextMessage,
$publicKey
);
// ...
$decrypted = sodium_crypto_box_seal_open(
$encrypted,
$keypair
);
Простой и безопасный. Libsodium будет доступен в PHP 7.2 или через PECL для более ранних версий PHP. Если вам нужен полифилл на чистом PHP, получите образец/sodium_компат.
Неохотно: Правильное использование RSA
Единственная причина использовать RSA в 2017 году: "Мне запрещено устанавливать расширения PECL, и поэтому я не могу используйте libsodium, и по какой-то причине вы также не можете использовать paragonie/sodium_compat".
Ваш протокол должен выглядеть примерно так:
- Сгенерируйте случайный ключ AES.
- Зашифруйте свое текстовое сообщение ключом AES, используя режим шифрования AEAD или, в противном случае, CBC, а затем HMAC-SHA256.
- Зашифруйте свой ключ AES (шаг 1) с помощью открытого ключа RSA, используя RSAES-OAEP +MGF1-SHA256
- Объедините свой ключ AES, зашифрованный RSA (шаг 3) и зашифрованное сообщение AES (шаг 2).
Вместо того, чтобы реализовывать это самостоятельно, ознакомьтесь с EasyRSA.
Да. Посмотрите на http://jerrywickey.com/test/testJerrysLibrary.php
В нем приведены примеры кода для шифрования и дешифрования RSA в PHP, а также шифрования RSA в javascript.
Если вы хотите зашифровать текст, а не просто базовые 10 чисел, вам также понадобится преобразование базы в базу. То есть преобразуйте текст в очень большое число. Текст на самом деле просто пишется в базе 63. 26 строчных букв плюс 26 прописных + 10 цифр + пробел. Код ибо это также ниже.
Параметр $GETN - это имя файла, в котором содержатся ключи для функций шифрования. Если вы не поймете этого, спросите. Я помогу.
На самом деле я вчера опубликовал всю эту библиотеку шифрования, но Брэд Ларсон, мод, убил ее и сказал, что такого рода вещи на самом деле не являются переполнением стека. Но вы все равно можете найти все примеры кода и всю библиотеку функций для выполнения шифрования и дешифрования клиент/сервер для AJAX по ссылке выше.
function RSAencrypt( $num, $GETn){
if ( file_exists( 'temp/bigprimes'.hash( 'sha256', $GETn).'.php')){
$t= explode( '>,', file_get_contents('temp/bigprimes'.hash( 'sha256', $GETn).'.php'));
return JL_powmod( $num, $t[4], $t[10]);
}else{
return false;
}
}
function RSAdecrypt( $num, $GETn){
if ( file_exists( 'temp/bigprimes'.hash( 'sha256', $GETn).'.php')){
$t= explode( '>,', file_get_contents('temp/bigprimes'.hash( 'sha256', $GETn).'.php'));
return JL_powmod( $num, $t[8], $t[10]);
}else{
return false;
}
}
function JL_powmod( $num, $pow, $mod) {
if ( function_exists('bcpowmod')) {
return bcpowmod( $num, $pow, $mod);
}
$result= '1';
do {
if ( !bccomp( bcmod( $pow, '2'), '1')) {
$result = bcmod( bcmul( $result, $num), $mod);
}
$num = bcmod( bcpow( $num, '2'), $mod);
$pow = bcdiv( $pow, '2');
} while ( bccomp( $pow, '0'));
return $result;
}
function baseToBase ($message, $fromBase, $toBase){
$from= strlen( $fromBase);
$b[$from]= $fromBase;
$to= strlen( $toBase);
$b[$to]= $toBase;
$result= substr( $b[$to], 0, 1);
$f= substr( $b[$to], 1, 1);
$tf= digit( $from, $b[$to]);
for ($i=strlen($message)-1; $i>=0; $i--){
$result= badd( $result, bmul( digit( strpos( $b[$from], substr( $message, $i, 1)), $b[$to]), $f, $b[$to]), $b[$to]);
$f= bmul($f, $tf, $b[$to]);
}
return $result;
}
function digit( $from, $bto){
$to= strlen( $bto);
$b[$to]= $bto;
$t[0]= intval( $from);
$i= 0;
while ( $t[$i] >= intval( $to)){
if ( !isset( $t[$i+1])){
$t[$i+1]= 0;
}
while ( $t[$i] >= intval( $to)){
$t[$i]= $t[$i] - intval( $to);
$t[$i+1]++;
}
$i++;
}
$res= '';
for ( $i=count( $t)-1; $i>=0; $i--){
$res.= substr( $b[$to], $t[$i], 1);
}
return $res;
}
function badd( $n1, $n2, $nbase){
$base= strlen( $nbase);
$b[$base]= $nbase;
while ( strlen( $n1) < strlen( $n2)){
$n1= substr( $b[$base], 0, 1) . $n1;
}
while ( strlen( $n1) > strlen( $n2)){
$n2= substr( $b[$base], 0, 1) . $n2;
}
$n1= substr( $b[$base], 0, 1) . $n1;
$n2= substr( $b[$base], 0, 1) . $n2;
$m1= array();
for ( $i=0; $i<strlen( $n1); $i++){
$m1[$i]= strpos( $b[$base], substr( $n1, (strlen( $n1)-$i-1), 1));
}
$res= array();
$m2= array();
for ($i=0; $i<strlen( $n1); $i++){
$m2[$i]= strpos( $b[$base], substr( $n2, (strlen( $n1)-$i-1), 1));
$res[$i]= 0;
}
for ($i=0; $i<strlen( $n1) ; $i++){
$res[$i]= $m1[$i] + $m2[$i] + $res[$i];
if ($res[$i] >= $base){
$res[$i]= $res[$i] - $base;
$res[$i+1]++;
}
}
$o= '';
for ($i=0; $i<strlen( $n1); $i++){
$o= substr( $b[$base], $res[$i], 1).$o;
}
$t= false;
$o= '';
for ($i=strlen( $n1)-1; $i>=0; $i--){
if ($res[$i] > 0 || $t){
$o.= substr( $b[$base], $res[$i], 1);
$t= true;
}
}
return $o;
}
function bmul( $n1, $n2, $nbase){
$base= strlen( $nbase);
$b[$base]= $nbase;
$m1= array();
for ($i=0; $i<strlen( $n1); $i++){
$m1[$i]= strpos( $b[$base], substr($n1, (strlen( $n1)-$i-1), 1));
}
$m2= array();
for ($i=0; $i<strlen( $n2); $i++){
$m2[$i]= strpos( $b[$base], substr($n2, (strlen( $n2)-$i-1), 1));
}
$res= array();
for ($i=0; $i<strlen( $n1)+strlen( $n2)+2; $i++){
$res[$i]= 0;
}
for ($i=0; $i<strlen( $n1) ; $i++){
for ($j=0; $j<strlen( $n2) ; $j++){
$res[$i+$j]= ($m1[$i] * $m2[$j]) + $res[$i+$j];
while ( $res[$i+$j] >= $base){
$res[$i+$j]= $res[$i+$j] - $base;
$res[$i+$j+1]++;
}
}
}
$t= false;
$o= '';
for ($i=count( $res)-1; $i>=0; $i--){
if ($res[$i]>0 || $t){
$o.= substr( $b[$base], $res[$i], 1);
$t= true;
}
}
return $o;
}