Использование открытого ключа, полученного от сервера C в клиенте Java - PullRequest
1 голос
/ 18 ноября 2011

У меня странные проблемы с использованием открытого ключа в клиенте Java.Я получаю открытый ключ от сервера C и знаю следующее: кодированный B64, ключ RSA X.509, и я должен использовать PKCS1Padding.До сих пор я сделал следующее, чтобы убедиться, что данные, передаваемые между клиентом и сервером, верны:

1) Содержание и длина данных, отправляемых с сервера, идентичны клиенту java

2) После того, как кодируется B64, данные и длина совпадают

3) Я также проверил, что данные между клиентом C и клиентом Java одинаковы, пока я не начну создаватьоткрытый ключ из декодированных данных.

Я столкнулся с проблемой, что клиент Java отправляет слишком много данных обратно на сервер после шифрования пароля шифром.Я пытался использовать разные методы при создании объекта с открытым ключом, но, похоже, ничего не работает.Я либо получаю ошибку " algid parse, а не последовательность " - или создается ключ, и в итоге я отправляю слишком много байтов данных (139 из Java против 128 из клиента C).Вот код (вычеркнул некоторые несущественные вещи).Все разбито на одну попытку / перехват, поскольку я пытался точно определить проблему:

byte[] pk = getKeyFromServer(); // 191 bytes 
String keyString = new String(pk);
byte[] decoded = decode(keyString); // 139 bytes

try {
    keySpec = new X509EncodedKeySpec(decoded);
} catch (Exception e) {  e.printStackTrace();}

try {
    keyFactory = KeyFactory.getInstance("RSA", "IBMJCE");
} catch (Exception e) {  e.printStackTrace();}

try {
    publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {  e.printStackTrace();}

try {
    cipher = Cipher.getInstance("RSA/SSL/PKCS1Padding", "IBMJCE");
} catch (Exception e) { e.printStackTrace(); }

try {
   cipher.init(Cipher.ENCRYPT_MODE, publicKey);
} catch (Exception e) { e.printStackTrace(); }

try {   sendEncrypted(cipher.doFinal(pwd.getBytes()));
} catch (Exception e) { e.printStackTrace(); }

Приведенный выше код встречается в исключении, которое я упоминал ранее, и если я удаляю части KeySpec и KeyFactory, ипереходя к следующему, я добираюсь до части шифрования, но затем я отправляю слишком много данных, и сервер не может расшифровать их (я получил показатель от копания).

java.math.BigInteger modulus = new java.math.BigInteger(decoded);
java.math.BigInteger exponent = new java.math.BigInteger("22111");

publicKey = new RSAPublicKey(modulus, exponent);

Так что я предполагаю, чтовопрос в том, делаю ли я что-то совершенно не так, или мне нужно больше узнать о том, что делает клиент C с открытым ключом, закодированным BASE64, прежде чем использовать его для шифрования и попытаться повторить это?Сейчас я не могу получить доступ к этой части: (

Я пытался использовать разные KeySpecs, PublicKeys и paddings, но результат всегда одинаков (хотя исключение может отличаться, когда я далеко от базыс KeySpec).

В противном случае связь между сервером и клиентом работает хорошо. Именно эта часть использует открытый ключ, который не работает.

РЕДАКТИРОВАТЬ: Просто хотел добавить открытый ключ String, если это что-то говорит:

Public key from server:
MIGIAoGBAMZawVoP6mHl0xD3Epn1l4S/6Ke20ZTNLKaXyi425NwhiE7LoTysAcpx
y3i9LXLVNGpdPNtpGD3mvlNJc/HfGQQ7NQpNyKpe5EzsODb1YCbODtfmaRODDW9B
qsrE8DCxI0g8gzu3NJTrUh4NfRaSBn9HaOnBUwiyQyihq2I6MB6bAgJWXw==

1 Ответ

1 голос
/ 22 ноября 2011

Не могли бы вы попробовать "RSA / ECB / PKCS1Padding" без "/ SSL" в середине?SSL использует специальную структуру, если я не ошибаюсь.

Кроме того: Кодировка не совместима с X509!Похоже, кодировка ключа - PKCS # 1, а X509 использует небольшую оболочку для этой кодировки!

Из PKCS # 1:

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

Из X509EncodedKeySpec:

SubjectPublicKeyInfo ::= SEQUENCE {
   algorithm AlgorithmIdentifier,
   subjectPublicKey BIT STRING }

Таким образом, вам необходимо добавить тег последовательности, длину, идентификатор алгоритма и тег BIT STRING и длину перед данными, которые вы получаете!Странно, что вы можете позволить ему делать что-либо вообще.

Для этой конкретной длины ключа и (странного) двухбайтового открытого показателя заголовок будет состоять из следующих байтов:

(byte) 0x30, (byte) 0x81, (byte) 0x9E, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A,
(byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x01,
(byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8C, (byte) 0x00, 

В качестве альтернативы,Вы также можете просто извлечь два целых числа из структуры и создать из них RSAPublicKeySpec.

...