Преобразование Public Key в String и String в Public Key

ЧТО ДЕЛАЮ: Создаю Public Key, преобразую его в строку и записываю строку в JSON, в котором передаю на сервер, где принимаю скриптом php и сохраняю эту строку в blob mysql. Затем запрашиваю эту строку, получаю ее в виде параметра в json, преобразую в Public Key и проверяю с его помощью цифровую подпись.

В ЧЕМ ПРОБЛЕМА: Если убрать из списка этих действий запись в json, отправку на сервер и получение с сервера json, т.е. если преобразовать Public Key в строку, а потом преобразовать строку обратно в Public Key, то все работает нормально, но если сохраняю строку в json и потом получаю строку из json то выдается ошибка: "java.security.spec.InvalidKeySpecException: encoded key spec not recognized: y value does not appear to be in correct group".

КАК ДЕЛАЮ:

// Создание Public Key:
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(2048);
KeyPair pair = keyGen.generateKeyPair();
publicKey = pair.getPublic();
privateKey = pair.getPrivate();
// Преобразование Public Key в массив байтов:
byte[] b = pub.getEncoded();
// Преобразование массива байтов в строку:
String s = byteArrayToString(b);

Далее передача строки s в виде параметра json на сервер, получение на сервере, сохранение скриптом php в blob mysql, затем запрос из клиента на сервер, получение строки из blob, запись в параметр json, получение json на клиенте, вынимание из json строки.

// Преобразование из строки в массив байтов:
byte[] b1 = stringToByte(s);
// Преобразование массива байтов в Public Key:
KeyFactory kf = KeyFactory.getInstance("DSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b1);
PublicKey pub1 = kf.generatePublic(publicKeySpec);

Далее - стандартная проверка цифровой подписи. Вот преобразования Public Key в строку и обратно:

    // Преобразование массива байт (byte[]) в строку:
    public static String byteArrayToString(byte[] bt) {
        int dLength = bt.length;
        // Выводим начальные значения:
        String bitsString = "";
        String result = "";

        for(byte datum : bt) {
            // преобразовать в биты:
            bitsString = Integer.toBinaryString((int)datum);
            // дополнить нулями до 8 символов:
//            while(bitsString.length() < 8) {
//                bitsString = "0" + bitsString;
//            }
            // поставить разделитель:
            bitsString = bitsString + "-";
            // добавить в общую строку:
            result = result + bitsString;
        }
        return result;
    }

    // Преобразование строки в массив байт (byte[]):
    public static byte[] stringToByte(String str) {
        // Строку в массив:
        String s;
        int ind = 0;
        // Определяем количество байт в полученной строке по количеству разделителей:
        int colByte = countEntries(str, "-");
        // Инициализируем байтовый массив по количеству байт:
        byte[] b = new byte[colByte];
        // Длина исходной строки:
        int slength = str.length();
        int j = 0;
        while(ind < slength) {
            // Индекс ближайшего разделителя:
            ind = str.indexOf("-");
            // Подстрока одного числа:
            s = str.substring(0, ind);
            //s1 = s1.replaceAll("[^0-9]", ""); // Убираем все символы кроме чисел.
            str = str.substring(ind+1,slength); // получаем оставшийся кусок строки
            slength = str.length();
            // Преобразование из двоичной в десятичное число:
            long i = Long.parseLong(s, 2); // Могут быть числа, большие диапазона int, поэтому используем long.
            // Добавить в массив byte[]:
            b[j] = (byte)i;
            j++;
        }
        return b;
    }

    // Определение количества подписей по количеству разделителей (сколько раз подстрока subStr встречается в строке str):
    public static int countEntries(String str, String subStr) {
        return (str.length() - str.replace(subStr, "").length())/subStr.length();
    }

ВОПРОС: что я делаю не так или в чем может быть дело?


Ответы (0 шт):