Java.security — как хранить ключи KeyPair в строке. Я получаю исключения из-за недопустимой кодировки DER

Создание пары ключей, кодирование и декодирование с помощью массива байтов работает нормально.

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

Я использовал string.getBytes() и new String(bytes) для преобразования массива байтов в строку и vv.

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

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- Invalid DER encoding, not ended

Решение, спасибо Джеймсу К. Полку, есть в ответе.

Вы не знаете. Вы храните их в байтовых массивах. String не является контейнером для двоичных данных.

user207421 10.04.2019 21:38

нет нет Нет Нет! Если вы должны хранить произвольные последовательности байтов в виде символьных данных, вам необходимо использовать соответствующую кодировку. Наиболее распространенной и широко поддерживаемой такой кодировкой является base64, так что используйте ее.

President James K. Polk 10.04.2019 21:50

@James K Polk, большое спасибо, это действительно помогает. Пожалуйста, добавьте в качестве ответа, и я буду v и +1.

tm1701 10.04.2019 23:22
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
840
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Спасибо, @Джеймс К Полк!! Это очень помогло мне в завершении моих экспериментов! Когда вы опубликуете ответ, я поставлю "V" и "+1" этому ответу!

Используя ответ Джеймса К. Полка, я переписал экспериментальный пример:

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class KeyPairToString {
    private static final String ALGORITHM = "RSA";

    private static byte[] encrypt(byte[] publicKey, byte[] inputData) throws Exception {
        PublicKey key = KeyFactory.getInstance(ALGORITHM)    /* ExceptionL Invalid DER encoding */
                .generatePublic(new X509EncodedKeySpec(publicKey));
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(inputData);
    }

    private static byte[] decrypt(byte[] privateKey, byte[] inputData) throws Exception {
        PrivateKey key = KeyFactory.getInstance(ALGORITHM)
                .generatePrivate(new PKCS8EncodedKeySpec(privateKey));
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(inputData);
    }

    private static KeyPair generateKeyPair()
            throws NoSuchAlgorithmException, NoSuchProviderException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
        keyGen.initialize(512, random);
        return keyGen.generateKeyPair();
    }

    private static String bytesToString(byte[] bytes) {
        return new String(bytes);
    }

    private static byte[] stringToBytes(String astring) {
        return astring.getBytes();
    }

    private static String bytesToEncodedString(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    private static byte[] encodedStringToBytes(String encodedString) {
        return Base64.getDecoder().decode(encodedString);
    }

    public static void main(String[] args) throws Exception {
        KeyPair generateKeyPair = generateKeyPair();

        byte[] publicKey = generateKeyPair.getPublic().getEncoded();
        byte[] privateKey = generateKeyPair.getPrivate().getEncoded();

        // Byte array
        String secretText = "hi this is secret johan here";
        byte[] encryptedData = encrypt(publicKey, secretText.getBytes());
        byte[] decryptedData = decrypt(privateKey, encryptedData);
        System.out.println(new String(decryptedData));

        // Now with Strings
        String encodedPublicKeyString = bytesToEncodedString(publicKey);
        String encodedPrivateKeyString = bytesToEncodedString(privateKey);
        String encryptedDataString = bytesToEncodedString(
                encrypt(encodedStringToBytes(encodedPublicKeyString), stringToBytes(secretText)));
        String decryptedDataString = bytesToString(
                decrypt(
                        encodedStringToBytes(encodedPrivateKeyString),
                        encodedStringToBytes(encryptedDataString)));
        System.out.println(new String(decryptedDataString));
    }
}

Другие вопросы по теме