Bouncy Castle CMS шифрование с открытым ключом - PullRequest
0 голосов
/ 26 апреля 2018

Я следую примеру: http://www.baeldung.com/java-bouncy-castle

И у меня есть пара вопросов:

public static byte[] encryptData(byte[] data,
  X509Certificate encryptionCertificate)
  throws CertificateEncodingException, CMSException, IOException {

    byte[] encryptedData = null;
    if (null != data && null != encryptionCertificate) {
        CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator
          = new CMSEnvelopedDataGenerator();

        JceKeyTransRecipientInfoGenerator jceKey 
          = new JceKeyTransRecipientInfoGenerator(encryptionCertificate);
        cmsEnvelopedDataGenerator.addRecipientInfoGenerator(transKeyGen);
        CMSTypedData msg = new CMSProcessableByteArray(data);
        OutputEncryptor encryptor
          = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC)
          .setProvider("BC").build();
        CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator
          .generate(msg,encryptor);
        encryptedData = cmsEnvelopedData.getEncoded();
    }
    return encryptedData;
}

Применяя это к моему сценарию реального мира, у меня есть толькооткрытый ключ RSA для получателя, а не весь сертификат X509.Я немного поковырялся, но я не уверен, как мне это сделать.Возможно ли это?

Другое дело, что я вижу, что JceCMSEncryptorBuilder принимает ASN1ObjectIdentifier.В настоящее время мы используем что-то вроде этого:

KeyGenerator cryptKeyGenerator = KeyGenerator.getInstance("AES", "BC");
cryptKeyGenerator.init(256);
Key encryptionKey = cryptKeyGenerator.generateKey();
Cipher symmetricCipher = Cipher.getInstance("AES/CTS/NoPadding", "BC");
symmetricCipher.init(Cipher.ENCRYPT_MODE, encryptionKey, new IvParameterSpec(ivBytes));

, а в классе CMSAlgorithm я не вижу никакой опции CTS.Я что-то упустил или есть способ по-прежнему использовать CTS?

1 Ответ

0 голосов
/ 26 апреля 2018

У меня есть только открытый ключ RSA для получателя, а не весь сертификат X509

В KeyTransRecipientInfo структуре CMS EnvelopedData можно использовать значение SubjectKeyIdentifier иногда присутствует в сертификате X.509 / PKIX как расширение , а Bouncy имеет перегруженный ctor для этого случая .Поскольку у вас нет сертификата, вам придется выяснить, какой метод использовался для расчета значения в сертификате (-ах), если получатель (-и) будут использовать сертификат, или пробовать разные догадки, пока не найдете его.это работает, или, если вы контролируете получателя (ей), просто выберите некоторые значения, которые он (они) примет.

org.bouncycastle.cert.X509ExtensionUtils и его два подкласса предоставляют методы для вычисления двух стандартных схем, но я нахожу их не более удобными, чем делать это напрямую.

В настоящее время мы используем ... AES / CTS / NoPadding ... и в классе CMSAlgorithm я не вижу никакой опции CTS

Это не только то, что в CMSAlgorithm.Существуют два соответствующих фактора:

  • любой конкретный шифр (в терминах JCA, преобразование), используемый в CMS / PKCS7. EnvelopedData должен идентифицироваться OID и условно параметрами

  • шифр, используемый для данного сообщения, должен поддерживаться отправителем и получателем или всеми получателями.

org.bouncycastle.cms.CMSAlgorithm это просто удобный сборник шифров и некоторых других вещей, таких как ключевые соглашения, которые имеют стандартизированные OID и реализуются BC, последний из которых фактически контролируется org.bouncycastle.cms.jcajce.EnvelopedDataHelper или нативный эквивалент , который, как вы можете видеть, поддерживает только режим CBC для поддерживаемых блочных шифров.(Оба также поддерживают RC4, но в качестве потокового шифра он не использует никакой режим. Плюс RC4 теперь очень непопулярен.)

Я не припоминаю, чтобы когда-либо видел какой-либо стандартизированный OID для шифра в режиме CTS.Если это правильно, вам придется выделить один, и, поскольку никто другой не будет реализовывать этот OID, ваши сообщения не будут взаимодействовать ни с кем.Если вы можете найти стандартный OID (или, по крайней мере, AlgId), который реализуют ваши коллеги, для BC вам придется создать свой собственный класс, соответствующий (interface) OutputEncryptor, что не так уж сложно, если выпосмотрите на приведенные выше источники, учитывая, что у вас есть провайдер или bc-native реализация базового шифра.

...