Расшифровка RSA с использованием модуля и показателя степени - PullRequest
0 голосов
/ 11 апреля 2011

Моя задача: Я зашифровал (RSA) данные и открытый ключ как модуль и показатель степени. Я должен написать код расшифровки.
Моя проблема с ним: Моя реализация не работает;) Насколько я знаю, философия проста "открытый текст" == rsa (public_key, rsa (private_key, "open text")) Редактировать: Точно мое предположение было неверным (Предположение является матерью всех глупостей;)). Это должно быть "open text" == rsa(private_key, rsa(public_key, "open text")), потому что в RSA открытый ключ используется для шифрования, а закрытый для расшифровки.

Я предполагал, что у меня может быть открытый ключ, который не соответствует личному ключу, используемому во время шифрования, поэтому для тестов я создал собственные ключи следующим образом:

openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Я получил модуль и экспоненту открытого ключа, используя команду:

openssl x509 -in server.crt -text

Для тестирования шифрования я использую код

//Reads private key from file
//StringPasswordFinder is my tmp implementation of PasswordFinder
PEMReader pemReader = new PEMReader(new FileReader("/path/to/server.key"), new StringPasswordFinder());
KeyPair keyPair = (KeyPair) pemReader.readObject();
PrivateKey pk = keyPair.getPrivate();
//text for encryption
String openText = "openText";
//encryption
Cipher rsaCipher = Cipher.getInstance("RSA", "BC");
rsaCipher.init(Cipher.ENCRYPT_MODE, pk);
byte[] encrypted = rsaCipher.doFinal(openText.getBytes("utf-8"));

А для расшифровки зашифрованного текста я использую код

//modulus hex got using openssl
byte[] modulus = Hex.decodeHex("very long hex".toCharArray());
//exponent hex got using openssl
byte[] exponent = Hex.decodeHex("010001".toCharArray());
//initialization of rsa decryption engine
RSAEngine rsaEngine = new RSAEngine();
rsaEngine.init(false, new RSAKeyParameters(false, new BigInteger(modulus), new BigInteger(exponent)));
//input - encrypted stream
ByteArrayInputStream bais = new ByteArrayInputStream(encrypted);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//reading blocks from the input stream and decrypting them
int bytesRead = 0;
byte[] block = new byte[rsaEngine.getInputBlockSize()];
while ((bytesRead = bais.read(block)) > -1) {
    baos.write(rsaEngine.processBlock(block, 0, bytesRead));
}
//dispalying decrypted text
System.out.println(new String(baos.toByteArray(), "utf-8"));

А ведь отображаемого текста нет. Кто-нибудь может показать мне, где я не прав?

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

1 Ответ

0 голосов
/ 11 апреля 2011

Я не очень знаком с java-библиотеками для RSA, когда я пытался внедрить RSA в java, я сам собирал все вычисления, но , если я вас правильно понял , я вижу 2 проблемы:

  1. данные должны быть зашифрованы открытым ключом и расшифрованы закрытым ключом, а не наоборот (поскольку каждый, кто имеет открытый ключ, сможет его расшифровать ...)
  2. открытый ключ должен совпадать с закрытым ключом, в противном случае любой пользователь с любым закрытым ключом сможет расшифровать данные, зашифрованные любым открытым ключом ...

Кроме того, для очень длинных данных не следует использовать шифрование с открытым ключом. Вместо этого зашифруйте данные в другом алгоритме (RC4, AES и т. Д.) И зашифруйте ключ в RSA (аналогично подходу PGP)

...