2015-11-24 1 views
0

Я хочу обменять симметричные ключи между клиентской и серверной программой, работающей на Java RMI.Обмен симметричными ключами между клиентом и сервером с использованием открытого ключа

Мой сервер делает открытый ключ:

KeyPairGenerator keyGen = null; 
try { 
    keyGen = KeyPairGenerator.getInstance("DSA", "SUN"); 
} catch (NoSuchAlgorithmException e) { 
    e.printStackTrace(); 
} catch (NoSuchProviderException e) { 
    e.printStackTrace(); 
} 
KeyPair pair = keyGen.generateKeyPair(); 
this.priv = pair.getPrivate(); 
this.pub = pair.getPublic(); 

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

//create cipher using server's public key 
Cipher cipher = null; 
try { 
    cipher = Cipher.getInstance(serverKey.getAlgorithm(), "SUN"); 
} catch (NoSuchAlgorithmException e) { 
    e.printStackTrace(); 
} catch (NoSuchPaddingException e) { 
    e.printStackTrace(); 
} catch (NoSuchProviderException e) { 
    e.printStackTrace(); 
} 
try { 
    cipher.init(Cipher.ENCRYPT_MODE, serverKey); 
} catch (InvalidKeyException e) { 
    e.printStackTrace(); 
} 

Но когда я запускаю программу, у меня есть исключение при инициализации шифра:

java.security.NoSuchAlgorithmException: No such algorithm: DSA 
at javax.crypto.Cipher.getInstance(Cipher.java:646) 
at javax.crypto.Cipher.getInstance(Cipher.java:568) 
at Client.main(Client.java:91) 

Я не понимаю, почему я получаю это исключение NoSuchAlgorithm. Я не понимаю этого, если я сделаю открытый ключ RSA, а не DSA, но RSA дает мне:

javax.crypto.IllegalBlockSizeException: 
Data must not be longer than 117 bytes 

Так что я должен использовать, чтобы безопасно отправлять запечатанный объект, содержащий мой симметричный ключ?

+0

Вместо этого вы не можете использовать стандартный 'SSLServerSocket'? TLS делает примерно то, что для вас – zapl

+0

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

+1

Нет такого алгоритма: DSA объясняется здесь: http://crypto.stackexchange.com/questions/2585/why-dsa-cannot-be-used-for-encryption и причина ошибки ограничения размера блока заключается в том, что RSA является а не обычный блочный шифр: http://stackoverflow.com/questions/685470/encrypted-data-size-using-rsa-encryption-rsacryptoserviceprovider или http://security.stackexchange.com/questions/1878/what-type -of-cipher-is-rsa и поэтому может использоваться только в определенных пределах, например в https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange – zapl

ответ

0

В качестве комментариев @zapl DSA не является алгоритмом шифрования, и RSA может шифровать только данные с размером меньше, чем размер ключа, за вычетом небольшой фиксированной накладной (11 байтов для PKCS1, которая по умолчанию и, следовательно, вы использовали , несколько больше для OAEP).

Хотя не в вашем опубликованном коде, я готов поспорить, проблема заключается в том, что вы пытаетесь запечатать объект SecretKey. Шифрование работает только с байтовыми (или битовыми) последовательностями, представленными в Java байтовыми массивами или иногда частями массивов, поэтому SealedObject фактически сериализует объект, который вы передаете его байтам, и шифрует эти байты и, наоборот, расшифровывает эти байты и десериализует их, сформировать объект. Сериализация Java имеет некоторые накладные расходы, и различные типы Key, в частности, организованы в иерархию, которая усугубляет это. Например, сериализация SecretKey от KeyGenerator.getInstance("TDES") составляет 282 байта, что слишком велико для RSA-1024, которое, как указано в вашем исключении, может составлять только 117 байт.

Вместо этого печать только байтов ключевого значения, полученных SecretKey.getEncoded(). На приемнике (сервере) верните байты в SecretKeySpec (с правильным алгоритмом, отправьте это, если не зафиксировать заранее), и вы можете фактически использовать его как Key для симметричного, даже не запуская его через фабрику (в отличие от асимметричных клавиш, которые имеют больше структуры). Даже простой byte[] имеет некоторые служебные данные сериализации, но этого недостаточно, чтобы вызвать проблему.

Смежные вопросы