1

I'm trying to replicate example from Java in c# with partial success

    CMSEnvelopedDataStreamGenerator gen = new CMSEnvelopedDataStreamGenerator();

    // NOTE: Uses the RECEIVER's PUBLIC encryption key
    gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(remoteEncryptionCert, rsaesOaepIdentifier()));

    OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_GCM).setProvider(BC).build();

    try (FileOutputStream fileStream = new FileOutputStream(OUTPUT_FILE); OutputStream encryptingOutputStream = gen.open(fileStream, encryptor)) {
                
                //
                // write file
                //
 
                encryptingOutputStream.flush();
            }

I've tried so far

Using System.Security.Cryptography.Pkcs

public byte[] Encrypt(byte[] plainBytes, X509Certificate2 recipientCert)
{
    // create ContentInfo
    ContentInfo plainContent = new ContentInfo(plainBytes);

    // EnvelopedCms represents encrypted data
    Oid encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.46"); // AES-256-GCM, 
    //Oid encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.42"); // AES-256-CBC
    EnvelopedCms encryptedData = new EnvelopedCms(plainContent, new AlgorithmIdentifier(encryptAlgoOid));

    // add a recipient
    CmsRecipient recipient = new CmsRecipient(recipientCert);

    // encrypt data with public key of recipient
    encryptedData.Encrypt(recipient); //Throws "Unknown cryptographic algorithm."

    // create PKCS #7 byte array
    byte[] encryptedBytes = encryptedData.Encode();

    // return encrypted data
    return encryptedBytes;
}

error stack trace

Unknown cryptographic algorithm.
   at Internal.Cryptography.Pal.Windows.PkcsPalWindows.EncodeHelpers.CreateCryptMsgHandleToEncode(CmsRecipientCollection recipients, Oid innerContentType, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
   at Internal.Cryptography.Pal.Windows.PkcsPalWindows.Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
   at System.Security.Cryptography.Pkcs.EnvelopedCms.Encrypt(CmsRecipientCollection recipients)
   at System.Security.Cryptography.Pkcs.EnvelopedCms.Encrypt(CmsRecipient recipient)
   at ConsoleApp1.Program.Encrypt() in Program.cs:line 91

Using Org.BouncyCastle.Cms

public byte[] Encrypt(X509Certificate2 recipientCert)
{
    // file stream
    FileStream fileEncrypted = new FileStream(pathToFile)

    CmsEnvelopedDataStreamGenerator gen = new CmsEnvelopedDataStreamGenerator();
    gen.AddKeyTransRecipient(recipientCert);

    var outEncryptedStream = gen.Open(fileEncrypted, "2.16.840.1.101.3.4.1.46"); 
    // Throws "KeyGenerator 2.16.840.1.101.3.4.1.46 not recognised." CmsEnvelopedDataGenerator doesn't 
    // have named constant for aes256gcm 

    return outEncryptedStream
}

error stack trace

KeyGenerator 2.16.840.1.101.3.4.1.46 not recognised.
   at Org.BouncyCastle.Security.GeneratorUtilities.GetKeyGenerator(String algorithm)
   at Org.BouncyCastle.Cms.CmsEnvelopedDataStreamGenerator.Open(Stream outStream, String encryptionOid)
   at ConsoleApp1.Program.Encrypt() in Program.cs:line 128

I have to make it work in a way so i can encrypt files with c# code and decrypt with java and vice versa.

What i noticed that i if i encrypt file in c# using Aes256CBC i can decrypt it in java, hows that possible? Does that mean that i implemented encryption wrong?

So what are mine options to make this work?

7
  • 1
    The default padding option in java and c# are different. So you have to specify the padding in c#. Commented Aug 29, 2020 at 9:45
  • ok, that maybe is another problem, but i cannot even finish encryption using AES256GCM algorithm Commented Aug 29, 2020 at 9:52
  • 2
    If the padding is wrong you will get an exception. The encryption class is able to determine bad inputs (inputs that do not match the paramers settings). See : stackoverflow.com/questions/21890805/… Commented Aug 29, 2020 at 11:20
  • 1
    There are lots of different parameters setting for the encryption classes. The exact same parameters need to be use for both encryption and decryption Commented Aug 29, 2020 at 11:59
  • 1
    You are getting an exception when using AES256GCM - mhm let my think which of the 100+ exceptions it is... It's difficult to give help without the complete error stack trace and the point (the line of code) it is pointing to. So kindly edit your post and add the stacktrace, thanks. Commented Aug 29, 2020 at 14:10

2 Answers 2

1

I'm sorry, as per https://github.com/bcgit/bc-csharp/blob/5bd4c8c70f80f1e7ead8e3c73459b78eb93d0ef7/crypto/src/security/GeneratorUtilities.cs it seems to be that AES-256-GCM mode is not available even in actual C# Bouncy Castle:

static GeneratorUtilities()
...
AddKgAlgorithm("AES256",
  "2.16.840.1.101.3.4.42",
  NistObjectIdentifiers.IdAes256Cbc,
  NistObjectIdentifiers.IdAes256Cfb,
  NistObjectIdentifiers.IdAes256Ecb,
  NistObjectIdentifiers.IdAes256Ofb,
  NistObjectIdentifiers.IdAes256Wrap);
...
Sign up to request clarification or add additional context in comments.

1 Comment

I knew that, but what are mine options? Is there any other library that i could use?
0

As per Michael Fehr comment AES-256-GCM module is not available in C# Bouncy Castle so we made Java Api and called from our codebase

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.