Generate CMS with already encrypted content

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Generate CMS with already encrypted content

3ric_T

Hi,

 

During the recovery workflow of an escrowed private key, I have :

-                      A private key, encrypted with an AES session key, ;

-                      This AES session key, encrypted with a provided external X.509 certificate

 

When I try to get, by hands, the clear private key, it works:

1-                  Decryption of the session key with the corresponding private key

2-                  Decryption of the private with the session key

So I am sure that the session key is a valid secret key and the private key a valid one too.

 

To send this recovered private key to its owner in a secure way, I want to build a CMS structure containing the encrypted session key and the encrypted private key. When I build such a CMS with the help of BC classes and clear private key, I can recover it by decrypting the CMS structure but that’s not what I want, because of the clear private key in memory:

 

X509Certificate externalCertX509 ;

CMSEnvelopedDataGenerator generator = new CMSEnvelopedDataGenerator();

generator.addRecipientInfoGenerator( new JceKeyTransRecipientInfoGenerator(externalCertX509).setProvider("BC") );

PrivateKey key;

CMSTypedData _content = new CMSProcessableByteArray(key.getEncoded());

CMSEnvelopedData _data = generator.generate(

                _content,

                new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC).setProvider("BC").build() );

When I dive into BC classes, I can use them to build a CMS with clear private key, letting BC generate the symmetric session key. Unfortunately, I cannot make it work with both encrypted session and private keys:

 

ASN1EncodableVector recipientInfos = new ASN1EncodableVector();

AlgorithmIdentifier encAlgId;

ASN1OctetString encContent;

X509Certificate externalCertX509 ;

final IssuerAndSerialNumber issuerAndSerialNumber = new IssuerAndSerialNumber(

                new JcaX509CertificateHolder(x509EncryptionCert).toASN1Structure());

final RecipientIdentifier recipientIdentifier = new RecipientIdentifier(issuerAndSerialNumber);

final JceAsymmetricKeyWrapper wrapper = new JceAsymmetricKeyWrapper(x509EncryptionCert);

byte[] wrappedKey;

recipientInfos.add(

                new RecipientInfo(

                               new KeyTransRecipientInfo(

                                               recipientIdentifier,

                                               wrapper.getAlgorithmIdentifier(),

                                               new BEROctetString(wrappedKey)

                               )

                )

);

final OutputEncryptor outputEncryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC).setProvider("BC").build();

encAlgId = outputEncryptor.getAlgorithmIdentifier();

encContent = new BEROctetString(encryptedKey);

EncryptedContentInfo eci = new EncryptedContentInfo(

new ASN1ObjectIdentifier(

                               CMSObjectIdentifiers.data.getId()),

               encAlgId,

               encContent);

ContentInfo contentInfo = new ContentInfo(

                CMSObjectIdentifiers.envelopedData,

                new EnvelopedData(null, new DERSet(recipientInfos), eci, (ASN1Set) null));

 

CMSEnvelopedData _data = new CMSEnvelopedData(contentInfo);

 

I am able to decrypt the content of the CMS structure, but I cannot built a private key with it, it fails with the error "java.security.InvalidKeyException: invalid key format":

 

final RecipientInformationStore recipientInformationStore = cmsEnvelopedData.getRecipientInfos();

KeyTransRecipientInformation keyTransRecipientInformation = (KeyTransRecipientInformation) recipientInformationStore.getRecipients().iterator().next();

 

JceKeyTransRecipient recipient = new JceKeyTransEnvelopedRecipient(recipientPrivateKey);

byte[] decryptedData = keyTransRecipientInformation.getContent(recipient);

KeyFactory kf = KeyFactory.getInstance("RSA");

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decryptedData);

PrivateKey decryptedPrivateKey = kf.generatePrivate(keySpec);

 

Could someone help me to find what I'm doing wrong?

Thanks a lot for reading and taking time to answer

√Čric