Пользователь
0,0
рейтинг
15 апреля 2015 в 11:49

Разработка → RSA шифрование в PHP (openssl), Android/Java, JavaScript и Go tutorial

RSA — это алгоритм шифрования с открытым ключем. Шифрование с открытым ключем весьма полезная вещь. RSA позволяет создать два ключа: открытый и закрытый. Разместить открытый ключ где-то и им шифровать, а расшифровать сможет только обладатель закрытого ключа.

Например, мы можем сделать веб магазин на ПХП, который будет принимать заказы с данными кредитных карт. Магазин на ПХП будет шифровать данные кредитных карт открытым ключем. Сам пхп-магазин расшифровать эти зашифрованные данные уже не сможет. Хорошее решение, хакер неожиданно так взломает веб магазин (написанный на ПХП), а карты зашифрованы.

Но как же владелец сайта будет получать доступ к картам? Ему нужно взять шифротекст, закрытый ключ и расшифровать. Можно представить, что закрытый ключ будет храниться в телефоне, и телефон может вытянуть шифротекст с админки через QR код. Но в разных языках реализация криптографии немного отличается, и моя статья как раз о том, как зашифровать текст на одном языке програмирования, а расшифровать на другом языке.

В чем могут быть отличия?
— как хранятся ключи;
— как хранится шифротекст: бинарная форма или в кодировке base64;
— паддинг.

Первым делом нам нужны ключи. Я предлагаю их создать с помощью openssl

openssl genrsa -out private.pem 512
openssl rsa -in private.pem -out public.pem -outform PEM -pubout


Для экономии места на экране я выбрал 512 бит, целесообразно использовать 1024 или 2048 бит. Например, SSL gitgub.com использует 2048.

Так же размер ключа определяет максимальный объем данных, которые вы можете зашифровать, но с учетом того, что мы будем использовать OPENSSL_PKCS1_PADDING (по умолчанию в ПХП), то из размера ключа следует вычесть 11 байт и при ключе 512 бит мы можем зашифровать 53 байта. Не использовать паддинг вообще опасно, если вы не знаете зачем он нужен.

Теперь у нас есть private.pem и public.pem. Эти ключи в текстовом формате, и их будет достаточно удобно использовать в примерах. Я хочу, чтобы каждая программа состояла из одного файла, так будет наглядней.

private.pem
-----BEGIN RSA PRIVATE KEY-----
MIIBPQIBAAJBALqbHeRLCyOdykC5SDLqI49ArYGYG1mqaH9/GnWjGavZM02fos4l
c2w6tCchcUBNtJvGqKwhC5JEnx3RYoSX2ucCAwEAAQJBAKn6O+tFFDt4MtBsNcDz
GDsYDjQbCubNW+yvKbn4PJ0UZoEebwmvH1ouKaUuacJcsiQkKzTHleu4krYGUGO1
mEECIQD0dUhj71vb1rN1pmTOhQOGB9GN1mygcxaIFOWW8znLRwIhAMNqlfLijUs6
rY+h1pJa/3Fh1HTSOCCCCWA0NRFnMANhAiEAwddKGqxPO6goz26s2rHQlHQYr47K
vgPkZu2jDCo7trsCIQC/PSfRsnSkEqCX18GtKPCjfSH10WSsK5YRWAY3KcyLAQIh
AL70wdUu5jMm2ex5cZGkZLRB50yE6rBiHCd5W1WdTFoe
-----END RSA PRIVATE KEY-----


public.pem
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALqbHeRLCyOdykC5SDLqI49ArYGYG1mq
aH9/GnWjGavZM02fos4lc2w6tCchcUBNtJvGqKwhC5JEnx3RYoSX2ucCAwEAAQ==
-----END PUBLIC KEY-----


Начнем с ПХП


encode.php

<?php
$pub = <<<SOMEDATA777
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALqbHeRLCyOdykC5SDLqI49ArYGYG1mq
aH9/GnWjGavZM02fos4lc2w6tCchcUBNtJvGqKwhC5JEnx3RYoSX2ucCAwEAAQ==
-----END PUBLIC KEY-----
SOMEDATA777;
$data = "PHP is my secret love.";
$pk  = openssl_get_publickey($pub);
openssl_public_encrypt($data, $encrypted, $pk);
echo chunk_split(base64_encode($encrypted));
?>

goo.gl/Xb7ayw

Получим, что-то типа (вы будете получать новый уникальный шифротекст при каждой попытке зашифровать текст):

JutBa0GLHzGrlygxwWr66cizw4W4za+DbzZweNM0iloCD7xEP9LclL013lcksJL5XhjW44U+oxpq
cX1ZSLhWuA==

decode.php

<?php
$key = <<<SOMEDATA777
-----BEGIN RSA PRIVATE KEY-----
MIIBPQIBAAJBALqbHeRLCyOdykC5SDLqI49ArYGYG1mqaH9/GnWjGavZM02fos4l
c2w6tCchcUBNtJvGqKwhC5JEnx3RYoSX2ucCAwEAAQJBAKn6O+tFFDt4MtBsNcDz
GDsYDjQbCubNW+yvKbn4PJ0UZoEebwmvH1ouKaUuacJcsiQkKzTHleu4krYGUGO1
mEECIQD0dUhj71vb1rN1pmTOhQOGB9GN1mygcxaIFOWW8znLRwIhAMNqlfLijUs6
rY+h1pJa/3Fh1HTSOCCCCWA0NRFnMANhAiEAwddKGqxPO6goz26s2rHQlHQYr47K
vgPkZu2jDCo7trsCIQC/PSfRsnSkEqCX18GtKPCjfSH10WSsK5YRWAY3KcyLAQIh
AL70wdUu5jMm2ex5cZGkZLRB50yE6rBiHCd5W1WdTFoe
-----END RSA PRIVATE KEY-----
SOMEDATA777;
$data = "JutBa0GLHzGrlygxwWr66cizw4W4za+DbzZweNM0iloCD7xEP9LclL013lcksJL5XhjW44U+oxpq cX1ZSLhWuA==";
$pk  = openssl_get_privatekey($key);
openssl_private_decrypt(base64_decode($data), $out, $pk);
echo $out;
?>

goo.gl/0CWTQ9

Теперь на Go


package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
	"strings"
)

func main() {
	b64 := `JutBa0GLHzGrlygxwWr66cizw4W4za+DbzZweNM0iloCD7xEP9LclL013lcksJL5XhjW44U+oxpq
cX1ZSLhWuA==
`
	b1, err := Base64Dec(b64)
	if err != nil {
		panic(err)
	}
	b2, err := RsaDecrypt(b1, privateKey)
	fmt.Println(string(b2), err)

	b1, err = RsaEncrypt([]byte("Go the best language"), publicKey)
	if err != nil {
		panic(err)
	}
	s1 := Base64Enc(b1)
	fmt.Println(s1)
	b1, err = Base64Dec(s1)
	b2, err = RsaDecrypt(b1, privateKey)
	fmt.Println(string(b2), err)

}

func Base64Enc(b1 []byte) string {
	s1 := base64.StdEncoding.EncodeToString(b1)
	s2 := ""
	var LEN int = 76
	for len(s1) > 76 {
		s2 = s2 + s1[:LEN] + "\n"
		s1 = s1[LEN:]
	}
	s2 = s2 + s1
	return s2
}

func Base64Dec(s1 string) ([]byte, error) {
	s1 = strings.Replace(s1, "\n", "", -1)
	s1 = strings.Replace(s1, "\r", "", -1)
	s1 = strings.Replace(s1, " ", "", -1)
	return base64.StdEncoding.DecodeString(s1)
}

func RsaDecrypt(ciphertext []byte, key []byte) ([]byte, error) {
	block, _ := pem.Decode(key)
	if block == nil {
		return nil, errors.New("private key error!")
	}
	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}

func RsaEncrypt(origData []byte, key []byte) ([]byte, error) {
	block, _ := pem.Decode(key)
	if block == nil {
		return nil, errors.New("public key error")
	}
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	pub := pubInterface.(*rsa.PublicKey)
	return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}

var publicKey = []byte(`
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALqbHeRLCyOdykC5SDLqI49ArYGYG1mq
aH9/GnWjGavZM02fos4lc2w6tCchcUBNtJvGqKwhC5JEnx3RYoSX2ucCAwEAAQ==
-----END PUBLIC KEY-----
`)

var privateKey = []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIIBPQIBAAJBALqbHeRLCyOdykC5SDLqI49ArYGYG1mqaH9/GnWjGavZM02fos4l
c2w6tCchcUBNtJvGqKwhC5JEnx3RYoSX2ucCAwEAAQJBAKn6O+tFFDt4MtBsNcDz
GDsYDjQbCubNW+yvKbn4PJ0UZoEebwmvH1ouKaUuacJcsiQkKzTHleu4krYGUGO1
mEECIQD0dUhj71vb1rN1pmTOhQOGB9GN1mygcxaIFOWW8znLRwIhAMNqlfLijUs6
rY+h1pJa/3Fh1HTSOCCCCWA0NRFnMANhAiEAwddKGqxPO6goz26s2rHQlHQYr47K
vgPkZu2jDCo7trsCIQC/PSfRsnSkEqCX18GtKPCjfSH10WSsK5YRWAY3KcyLAQIh
AL70wdUu5jMm2ex5cZGkZLRB50yE6rBiHCd5W1WdTFoe
-----END RSA PRIVATE KEY-----
`)


play.golang.org/p/nsyAw5kYDt

Go Playground всегда дают одни и те же случайные числа и поэтому результат:

aOleRSXhBT1XR7Al9cxdmM/8KnM2CvQdnNqnvwtq1ivFJ1aITxJUCuTw8ZRB8mY+elhoiUmC4UjM
mwyTKmjqQw==

JavaScript шифрование


Шифровать я буду с помощью jsEncrypt:

$(function () {
  $('#but').click(function(){
     var pub = $('#pub').val();
     var crypt = new JSEncrypt();
     crypt.setPublicKey(pub);
     var data = $('#data').val();
     $('#out').val(crypt.encrypt(data));
  });
});


cossackpyra.github.io/april14/html/encrypt.html

И получил:

C2uWXwp6OsxLKnr3cXpJIf/RcPzgjlxNXj8IX2R47binEo2dLFhJISDnOioQaM8kAl/lqSSOCLdrYP12Tc/YXQ==

$(function () {
  $('#but').click(function(){
     var key = $('#key').val();
     var crypt = new JSEncrypt();
     crypt.setPrivateKey(key);
     var data = $('#data').val();
     $('#out').val(crypt.decrypt(data));
  });
});

cossackpyra.github.io/april14/html/decrypt.html

Android не Java


Java — это так много всего, и ни фига нет.

В Android есть android.util.Base64, а Java 8 java.util.Base64, а еще есть org.apache.commons.codec.binary.Base64.

Java не умеет читать сертификаты в PEM формате, какие задачи и цели ставило руководство перед создателями java.security и javax.crypto — это мрак, но явно не экономить место на диске.

В Bouncy Castle есть PEMParser. Но Bouncy Castle в онлайн редактор не подцепишь, а в Android используется непонятно какой Bouncy Castle. Поэтому есть Spongy Castle, но это уже будет другая графа в реализации криптографии в форме «Supplement No. 5 to Part 742—Encryption Registration» на пункты 6 и 7 уже не ответишь «нет, нет».

SNAP-R
(6) Do the products incorporate encryption components produced or furnished by non-U.S. sources or vendors? (If unsure, please explain.)

No.

(7) With respect to your company's encryption products, are any of them manufactured outside the United States? If yes, provide manufacturing locations. (Insert “not applicable”, if you are not the principal producer of encryption products.)

No.


Поэтому из private.pem можно вынуть модуль, приватную и публичную экспоненты. (Это допустимо, я изначально ключи создал с помощью openssl.)

openssl rsa -in private.pem -text -noout
Private-Key: (512 bit)
modulus:
    00:ba:9b:1d:e4:4b:0b:23:9d:ca:40:b9:48:32:ea:
    23:8f:40:ad:81:98:1b:59:aa:68:7f:7f:1a:75:a3:
    19:ab:d9:33:4d:9f:a2:ce:25:73:6c:3a:b4:27:21:
    71:40:4d:b4:9b:c6:a8:ac:21:0b:92:44:9f:1d:d1:
    62:84:97:da:e7
publicExponent: 65537 (0x10001)
privateExponent:
    00:a9:fa:3b:eb:45:14:3b:78:32:d0:6c:35:c0:f3:
    18:3b:18:0e:34:1b:0a:e6:cd:5b:ec:af:29:b9:f8:
    3c:9d:14:66:81:1e:6f:09:af:1f:5a:2e:29:a5:2e:
    69:c2:5c:b2:24:24:2b:34:c7:95:eb:b8:92:b6:06:
    50:63:b5:98:41
prime1:
    00:f4:75:48:63:ef:5b:db:d6:b3:75:a6:64:ce:85:
    03:86:07:d1:8d:d6:6c:a0:73:16:88:14:e5:96:f3:
    39:cb:47
prime2:
    00:c3:6a:95:f2:e2:8d:4b:3a:ad:8f:a1:d6:92:5a:
    ff:71:61:d4:74:d2:38:20:82:09:60:34:35:11:67:
    30:03:61
exponent1:
    00:c1:d7:4a:1a:ac:4f:3b:a8:28:cf:6e:ac:da:b1:
    d0:94:74:18:af:8e:ca:be:03:e4:66:ed:a3:0c:2a:
    3b:b6:bb
exponent2:
    00:bf:3d:27:d1:b2:74:a4:12:a0:97:d7:c1:ad:28:
    f0:a3:7d:21:f5:d1:64:ac:2b:96:11:58:06:37:29:
    cc:8b:01
coefficient:
    00:be:f4:c1:d5:2e:e6:33:26:d9:ec:79:71:91:a4:
    64:b4:41:e7:4c:84:ea:b0:62:1c:27:79:5b:55:9d:
    4c:5a:1e


В Java это будет выглядеть так:

// Private key
		BigInteger modulus = new BigInteger(
				"BA9B1DE44B0B239DCA40B94832EA238F40AD81981B59AA687F7F1A75A319ABD9334D9FA2CE25736C3AB4272171404DB49BC6A8AC210B92449F1DD1628497DAE7",
				16);
		BigInteger exp = new BigInteger(
				"00a9fa3beb45143b7832d06c35c0f3183b180e341b0ae6cd5becaf29b9f83c9d1466811e6f09af1f5a2e29a52e69c25cb224242b34c795ebb892b6065063b59841",
				16);

//Public Key

		BigInteger modulus = new BigInteger(
				"BA9B1DE44B0B239DCA40B94832EA238F40AD81981B59AA687F7F1A75A319ABD9334D9FA2CE25736C3AB4272171404DB49BC6A8AC210B92449F1DD1628497DAE7",
				16);
		BigInteger pubExp = new BigInteger("010001", 16);



Вся программа на Java 8:

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;

import java.util.Base64;

//import javax.xml.bind.DatatypeConverter;

public class HelloWorld {

	public static void main(String[] args) throws Exception {
		try {
			byte[] b1 = decrypt("JutBa0GLHzGrlygxwWr66cizw4W4za+DbzZweNM0iloCD7xEP9LclL013lcksJL5XhjW44\nU+oxpqcX1ZSLhWuA==");
			String s1 = new String(b1, "UTF-8");
			System.out.println(s1);
			byte[] b2 = encrypt("Java kills".getBytes("UTF-8"));
			String s2 = Base64.getEncoder().encodeToString(b2);
			System.out.println(s2);
			byte[] b3 = decrypt(s2);
			String s3 = new String(b3, "UTF-8");
			System.out.println(s3);

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static byte[] decrypt(String key) throws Exception {

		BigInteger modulus = new BigInteger(
				"BA9B1DE44B0B239DCA40B94832EA238F40AD81981B59AA687F7F1A75A319ABD9334D9FA2CE25736C3AB4272171404DB49BC6A8AC210B92449F1DD1628497DAE7",
				16);
		BigInteger exp = new BigInteger(
				"00a9fa3beb45143b7832d06c35c0f3183b180e341b0ae6cd5becaf29b9f83c9d1466811e6f09af1f5a2e29a52e69c25cb224242b34c795ebb892b6065063b59841",
				16);

		RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulus, exp);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		PrivateKey privKey = kf.generatePrivate(keySpec);

		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, privKey);

		byte[] decodedStr = Base64.getDecoder().decode(
				key.replace("\n", "").replace("\r", "").replace(" ", ""));
		byte[] plainText = cipher.doFinal(decodedStr);

		return plainText;
	}

	private static byte[] encrypt(byte[] b1) throws Exception {
		BigInteger modulus = new BigInteger(
				"BA9B1DE44B0B239DCA40B94832EA238F40AD81981B59AA687F7F1A75A319ABD9334D9FA2CE25736C3AB4272171404DB49BC6A8AC210B92449F1DD1628497DAE7",
				16);
		BigInteger pubExp = new BigInteger("010001", 16);

		RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, pubExp);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		PublicKey publicKey = kf.generatePublic(keySpec);

		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);

		// byte[] decodedStr = Base64.decode(key, Base64.DEFAULT);
		byte[] plainText = cipher.doFinal(b1);

		return plainText;
	}
}



goo.gl/t27IWw
(Надо нажать Compile, Execute)
ik1Dvev7AffP+mOgxkbnYmpZrN9nGCKEzwCA4qsADcSKZFDYC/32B4uzUNSH8D+yCjBbrE5HUDL6vs6W5idG6Q==


Android программа
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;

import android.util.Base64;
import android.util.Log;

public class TestX {

	public static byte[] decrypt(String key) throws Exception {

		BigInteger modulus = new BigInteger(
				"BA9B1DE44B0B239DCA40B94832EA238F40AD81981B59AA687F7F1A75A319ABD9334D9FA2CE25736C3AB4272171404DB49BC6A8AC210B92449F1DD1628497DAE7",
				16);
		BigInteger exp = new BigInteger(
				"00a9fa3beb45143b7832d06c35c0f3183b180e341b0ae6cd5becaf29b9f83c9d1466811e6f09af1f5a2e29a52e69c25cb224242b34c795ebb892b6065063b59841",
				16);

		RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulus, exp);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		PrivateKey privKey = kf.generatePrivate(keySpec);

		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, privKey);

		byte[] decodedStr = Base64.decode(key, Base64.DEFAULT);
		byte[] plainText = cipher.doFinal(decodedStr);

		return plainText;
	}

	public static void test() {
		try {
			byte[] b1 = decrypt("JutBa0GLHzGrlygxwWr66cizw4W4za+DbzZweNM0iloCD7xEP9LclL013lcksJL5XhjW44U+oxpq\ncX1ZSLhWuA==");
			String s1 = new String(b1, "UTF-8");
			Log.i("TEST", s1);
			byte[] b2 = encrypt("Java kills".getBytes("UTF-8"));
			String s2 = Base64.encodeToString(b2, Base64.CRLF);
			Log.i("TEST", s2);
			byte[] b3 = decrypt(s2);
			String s3 = new String(b3, "UTF-8");
			Log.i("TEST", s3);

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static byte[] encrypt(byte[] b1) throws Exception {
		BigInteger modulus = new BigInteger(
				"BA9B1DE44B0B239DCA40B94832EA238F40AD81981B59AA687F7F1A75A319ABD9334D9FA2CE25736C3AB4272171404DB49BC6A8AC210B92449F1DD1628497DAE7",
				16);
		BigInteger pubExp = new BigInteger("010001", 16);

		RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, pubExp);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		PublicKey publicKey = kf.generatePublic(keySpec);

		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);

		byte[] plainText = cipher.doFinal(b1);

		return plainText;
	}
}



КО: шифровать можно не текст, а AES ключ.

Всем весны и удачи.
Ну как?

Проголосовало 140 человек. Воздержался 71 человек.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

@pyra
карма
23,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (14)

  • +3
    Java — это так много всего, и ни фига нет.


    Однако, как точно :)
    • –1
      > Но Bouncy Castle в онлайн редактор не подцепишь

      В этом Java виновата?
      • –1
        Я ночью в темноте шел по квартире и ударился головой о дверь. Дверь виновата?
      • +1
        Я не про это. Я вообще. В Java много библиотек доступно через Maven, но очень часто нет именно того, что нужно.
        • 0
          Ни разу такого не было. Но, возможно, у меня просто не было таких специфических задач, как у вас.
          • 0
            У меня Android. Требования по версии Java, потреблению памяти и производительности чуть разные…
            • 0
              Вот если взять Base64, то меня смущает, что он появился аж Java 8,
              за то до Java8 был
              docs.oracle.com/javase/7/docs/api/javax/xml/bind/DatatypeConverter.html умеющий Base64

              а андроиде есть
              android.util.Base64
              но почему они все городят свой?
              • +1
                Потому что основная на Android долгое время была пятёрка, наверное.
  • 0
    > Сам пхп-магазин расшифровать эти зашифрованные данные уже не сможет. Хорошее решение, хакер неожиданно так взломает веб магазин (написанный на ПХП), а карты зашифрованы.
    Зато сможет «расшифровать» все шифруемые данные в будущем.
    • 0
      ПХП это король shared хостинга, а там бывает, один пользователь может получить доступ к файлам другого пользователя, программа в cgi-bin может на некоторых хостингах прочитать исходный код ПХП файла из аккаунта другого пользователя например /home/vasyapupkin/www/conf.php
      • +3
        Это вы продолжаете набрасывать или просто так написали?
  • +2
    Магазин на ПХП будет шифровать данные кредитных карт открытым ключем. Сам пхп-магазин расшифровать эти зашифрованные данные уже не сможет. Хорошее решение, хакер неожиданно так взломает веб магазин (написанный на ПХП), а карты зашифрованы.


    Почитайте PCI и пообещайте, что больше не будете никогда сами хранить номера кредиток.
    • 0
      я не храню кредитки и не принимаю их. это вступление. статья о том как реализовать аналоги openssl_get_publickey, а вступление объясняет зачем это нужно
  • 0
    Буду очень признателен, если сможете дописать пример для PHP, в котором сначала публичный ключ формируется из модуля и экспоненты (изначально больше ничего не имею), а далее уже им шифруются данные. Интересует именно алгоритм RSA/ECB/PKCS1 Padding.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.