Ваш "ключ" не является действительным открытым ключом. Это строка Base64, которая при декодировании выдает последовательность из 129 байтов, первый из которых 0x00, а затем 0x93. Это недопустимый формат для открытого ключа RSA, но он подозрительно выглядит как кодирование со знаком с прямым порядком байтов 1024-битного целого числа (т. Е. Тип кодирования, возвращаемый BigInteger.toByteArray()
и используемый в значениях "INTEGER" ASN.1) ). Открытый ключ RSA номинально состоит из двух целых чисел, одно из которых является модулем , а другое - открытым показателем . Типичный модуль RSA имеет длину 1024 бита, поэтому есть вероятность, что у вас здесь есть модуль. Вам все еще нужен открытый показатель для завершения ключа.
X509EncodedKeySpec
ожидает кодирования DER структуры ASN.1, которая идентифицирует алгоритм как RSA, и содержит вложенную кодированную структуру, которая сама содержит два целых числа для открытого ключа RSA. Сборка такой структуры вручную может оказаться сложной (это выполнимо, но требует некоторого глубокого понимания ASN.1). Более простой способ - использовать RSAPublicKeySpec
:
String modulusBase64 = "..."; // your Base64 string here
BigInteger modulus = new BigInteger(1,
new Base64Encoder.decode(modulusBase64.getBytes("UTF-8")));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec ks = new RSAPublicKeySpec(modulus, pubExp);
RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(KeySpec);
В вышеприведенном "pubExp
" должно быть BigInteger
, содержащим открытый показатель, который вы не даете. 3 и 65537 являются традиционными значениями общедоступного показателя, но возможны и другие, и вы не предоставляете достаточно информации, чтобы различать общедоступные показатели (т. Е. Ваш код будет работать, даже если вы не используете правильный). По сути, у вас есть только половина открытого ключа; Вы должны попросить того, кто дал вам эту половину, послать вам и другую половину.
Примечание: String.getBytes()
использует кодировку платформы по умолчанию, которая не всегда одинакова. Если вы настаиваете на преобразовании строки в последовательность байтов, вам следует использовать явное имя кодировки, например "UTF-8"
, в противном случае вы можете столкнуться с проблемами, если ваш код когда-либо будет работать, например, в русской или китайской системе. Кроме того, я не знаю, откуда взялся ваш класс Base64Encoder
(он не является частью стандартного API Java), но есть вероятность, что он также может работать непосредственно над String
или StringReader
, делая шаг преобразования нет необходимости.