0

I'm following the example here: http://www.baeldung.com/java-bouncy-castle

And I've got a couple of questions:

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;
}

Applying this to my real world scenario, I only have an RSA public key for the recipient and not the whole X509Certificate. I poked around a bit, but I'm not sure how I could make that work. Is it possible?

The other thing is that I see the JceCMSEncryptorBuilder is takes an ASN1ObjectIdentifier. We're currently using doing something like this:

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));

and in the CMSAlgorithm class I don't see any CTS option. Am I missing something or is there a way to still use CTS?

rschlachter
  • 720
  • 1
  • 9
  • 20

1 Answers1

1

I only have an RSA public key for the recipient and not the whole X509Certificate

The KeyTransRecipientInfo structure of CMS EnvelopedData can use the SubjectKeyIdentifier value sometimes present in the X.509/PKIX certificate as an extension and Bouncy has an overloaded ctor for this case. Since you don't have the cert, you'll have to find out what method was used to calculate the value in the cert(s?) if the recipient(s) will use a cert, or try different guesses until you find one that works, or if you control the recipient(s) just choose some value(s) that it(they) will accept.

org.bouncycastle.cert.X509ExtensionUtils and its two subclasses provide methods for computing the two standard schemes, but I find them no more convenient than doing it directly.

We're currently using ... AES/CTS/NoPadding ... and in the CMSAlgorithm class I don't see any CTS option

It's not just what's in CMSAlgorithm. There are two relevant factors:

  • any specific cipher (in JCA terms, transformation) used in CMS/PKCS7 EnvelopedData must be identified by an OID and conditionally parameters

  • the cipher used for a given message must be supported by the sender and the recipient or all recipients.

org.bouncycastle.cms.CMSAlgorithm is just a handy compendium of ciphers and some other things like keyagreements that both have standardized OIDs and are implemented by BC, which latter is actually controlled by org.bouncycastle.cms.jcajce.EnvelopedDataHelper or the bc-native equivalent which as you can see support only CBC mode for the supported block ciphers. (Both also support RC4 but as a stream cipher it does not use any mode. Plus RC4 is now very unpopular.)

I don't recall ever seeing any standardized OID for a cipher in CTS mode. If that's right, you'd have to allocate one, and since no one else will implement that OID your messages will not be interoperable with anybody. If you can find a standard OID (or at least AlgId) that your peer(s) implement, for BC you'll have to create your own class conforming to (interface) OutputEncryptor, which isn't all that complicated if you look at the sources above given that you have either a provider or bc-native implementation of the underlying cipher.

Community
  • 1
  • 1
dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70