У меня есть сервер, написанный на Java, который перед отправкой клиенту преобразует свой ключ RSA в формат XML, используемый .NET:
public String getPublicKeyXML() {
try {
KeyFactory factory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec publicKey = factory.getKeySpec(this.keyPair.getPublic(), RSAPublicKeySpec.class);
byte[] modulus = publicKey.getModulus().toByteArray();
byte[] exponent = publicKey.getPublicExponent().toByteArray();
String modulusStr = Base64.encodeBytes(modulus);
String exponentStr = Base64.encodeBytes(exponent);
String format =
"<RSAKeyValue>" +
"<Modulus>%s</Modulus>" +
"<Exponent>%s</Exponent>" +
"</RSAKeyValue>";
return String.format(format, modulusStr, exponentStr);
} catch (Exception e) {
this.server.logException(e);
return "";
}
}
Клиент, написанный на C #, затем загружает ключ и использует его для шифрования 256-битного ключа AES:
public static byte[] encrypt(string xmlKey, byte[] bytes)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(xmlKey);
byte[] cipherBytes = rsa.Encrypt(bytes, false);
rsa.Clear();
return cipherBytes;
}
Затем сервер должен расшифровать ключ AES, используя свой закрытый ключ RSA:
public byte[] decrypt(byte[] data) {
try {
PrivateKey privateKey = this.keyPair.getPrivate();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherData = cipher.doFinal(data);
return cipherData;
} catch (Exception e) {
this.server.logException(e);
return new byte[0];
}
}
Однако сервер выходит из строя с сообщением об ошибке «Данные не должны быть длиннее 384 байта». Посмотрев на данные, которые нужно расшифровать, я заметил, что это 385 байт. Я попытался увеличить длину ключа RSA, и теперь сервер сообщает мне, что данные не должны быть длиннее 512 байт, в то время как зашифрованные данные от клиента составляют 513 байт. Почему зашифрованные данные всегда на один байт длиннее ожидаемого?
РЕДАКТИРОВАТЬ:
Вот пример ключа в формате XML, который передается с сервера клиенту:
<RSAKeyValue><Modulus>ANsMd2dCF6RsD5v5qjlHEjHm0VWD99gSYHP+pvyU8OgNL9xM5+o+yMAxWISOwMii9vJk1IzYGf18Fj2sMb5BsInlG2boZHb6KHh7v8ObPa4MuwB/U63i8AVU3N/JTugaPH0TKvo1WNUooXEHT23nOk+vh1QipzgKQYGl68qU35vKmpNAa79l1spXA66LckTWal4art9T08Rxgn9cMWujlF+wh9EQKQoxxgj4gCoXWRDTFYjRo/Mp5xDPwNjloTs/vFCPLvY7oI+lVrHhrPyz1R473ZuEhZm+rSeGBcY9I8vhg0AIixN7KYBLhrIecmqoNZHi6LohjD2F9zhdLaTU0IIU8eeKpbEZ5eB1kYngMONBq3A/IoG0Qa/7EcSAMMspBEObffK9kCNzvnbFg5wLuy8EHNaK3nmnuTppgCwCyNqZyHeAbZaUBjNguLhHtqkHFiPJ063Xesj9UbSsCmlBliGTDXWfeJANnjGP6D3R+uLXVy9SZe+cY92JW3eZA2k//w==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
Я подтвердил, что отправленные данные совпадают с полученными.
Удаление последнего байта приводит к возникновению исключения BadPaddingException. Я тоже пробовал сбивать первый байт, с тем же результатом.
getPublicKeyXML
генерирует слишком большой модуль? - person Jesse C. Slicer   schedule 31.07.2012