Java — шифрование с помощью ключа RSA

Я уже некоторое время борюсь с этой проблемой. Дело в том, что я должен отправить строку PEM на сервер, который ожидает последний шаг следующего:

  • Ключ шифрования типа 3DES или AES-256.
  • Этот ключ, зашифрованный ключом RSA.
  • Этот вывод, закодированный в Base64 и в формате PEM.

Вот что я получил до сих пор:

  • На основе ключа RSA, полученного с сервера, я создаю шифр:

     Cipher rsa = Cipher.getInstance("RSA");
    
     rsa.init(Cipher.ENCRYPT_MODE, (RSAPublicKey) obj);
    
  • Позже я создаю ключ AES:

    //IV. 
    byte[] bytes = new byte[16];
    SecureRandom random = new SecureRandom();
    random.nextBytes(bytes);
    
    Map<String, byte[]> aes = new HashMap<String, byte[]>();
    
    aes.put("IV", ConversionUtil.toHex(bytes, 8).getBytes());
    
    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    
    keyGen.init(256);
    Key encryptionKey = keyGen.generateKey();
    
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    
    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, new IvParameterSpec(ConversionUtil.toHex(bytes, 8).getBytes()));
    
    aes.put("key", cipher.doFinal(encryptionKey.getEncoded()));
    

Используйте все это для создания строки PEM:

            StringBuilder sb = new StringBuilder();
            sb.append(StringUtils.repeat("-", 5));
            sb.append("BEGIN PEM file");
            sb.append(StringUtils.repeat("-", 5));
            sb.append("\n");

            sb.append("Proc-Type: 4,ENCRYPTED\n");
            sb.append("DEK-Info: " + "AES-256-CBC" + "," + new String(aes.get("IV")) + "\n");
            sb.append("");
            sb.append(Base64.encode(rsa.doFinal(aes.get("key"))));

            sb.append("\n");
            sb.append(StringUtils.repeat("-", 5));
            sb.append("END PEM file");
            sb.append(StringUtils.repeat("-", 5));

А затем отправьте это на сервер, который выдает следующую ошибку:

3936: ошибка: 0906D06C: подпрограммы PEM: PEM_read_bio: нет стартовой строки:.\crypto\pem\pem_lib.c:698:

У меня не так много информации об ошибке, но я хотел проверить, не делаю ли я что-то не так в процессе, поскольку кажется, что ошибка связана с непризнанием PEM.

Дайте знать, если у вас появятся вопросы.

Спасибо!


person bassprodukt    schedule 05.12.2012    source источник
comment
Вы должны шифровать с помощью RSA, а вы шифруете ключ с помощью AES   -  person Amit Deshpande    schedule 05.12.2012
comment
Ммм, возможно, вы правы, сейчас я пытаюсь предоставить IV для шифра RSA, но получаю эту ошибку: cipher.init(Cipher.ENCRYPT_MODE, (RSAPublicKey) obj, new IvParameterSpec(iv)); java.security.InvalidAlgorithmParameterException: параметры не поддерживаются   -  person bassprodukt    schedule 05.12.2012
comment
Проверьте образец здесь, вам нужен ключ RSA.   -  person Amit Deshpande    schedule 05.12.2012
comment
Да, у меня есть это, но мне также нужно предоставить IV, поскольку сервер будет использовать его вместе с ключом RSA, который он предоставляет для расшифровки ключа AES/3DES, который я сделал.   -  person bassprodukt    schedule 05.12.2012
comment
Это не способ обеспечить IV. IV не нуждается в шифровании, им также можно поделиться публично   -  person Amit Deshpande    schedule 05.12.2012
comment
Вы правы, мне не нужно шифровать ключ с помощью шифра, я сейчас просто шифрую его с помощью RSA, но у меня все еще есть проблемы.   -  person bassprodukt    schedule 05.12.2012


Ответы (1)


Сообщается о конкретной ошибке, поскольку между тире и оператором BEGIN не должно быть пробелов. Я не знаю о других проблемах, но, похоже, вам предстоит некоторая работа, чтобы соответствовать точным входным требованиям. Убедитесь, что вы точно понимаете, что ожидается, иначе вам, возможно, придется попробовать разные форматы "до отвращения".

person Maarten Bodewes    schedule 05.12.2012
comment
Вы просто попали в точку. Мне удалось добиться некоторых успехов в этом, теперь я борюсь с ожидаемыми возвратами вагонов. Можно ли как-то вручную вставить их без учета фактической конфигурации системы? Поскольку я сейчас пытаюсь использовать \n и \r, но на фактическом выходе есть лишние, которые я не вставлял. Я понимаю, что система имеет некоторое влияние на то, как создаются \n и \r. - person bassprodukt; 06.12.2012
comment
Система не должна вставлять возврат каретки/перевод строки. Скорее всего, что-то не так в коде вашего приложения. Продолжайте отлаживать, в конце концов вы доберетесь туда :) - person Maarten Bodewes; 06.12.2012