使用envelopedCms中的aes256gcm算法加密/解密文件时出现问题。我的选择是什么?

huangapple go评论82阅读模式
英文:

Problem with encrypt/decrypting files using aes256gcm algorithm in envelopedCms. What are mine options?

问题

我试图在C#中部分成功地复制了一个Java示例,以下是代码部分:

Java示例:
CMSEnvelopedDataStreamGenerator gen = new CMSEnvelopedDataStreamGenerator();
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)) {
    // 写入文件
    encryptingOutputStream.flush();
}

C#尝试:

使用 System.Security.Cryptography.Pkcs 命名空间:

public byte[] Encrypt(byte[] plainBytes, X509Certificate2 recipientCert)
{
    ContentInfo plainContent = new ContentInfo(plainBytes);
    Oid encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.46"); // AES-256-GCM
    EnvelopedCms encryptedData = new EnvelopedCms(plainContent, new AlgorithmIdentifier(encryptAlgoOid));
    CmsRecipient recipient = new CmsRecipient(recipientCert);
    encryptedData.Encrypt(recipient);
    byte[] encryptedBytes = encryptedData.Encode();
    return encryptedBytes;
}

错误堆栈跟踪:
Unknown cryptographic algorithm.

使用 Org.BouncyCastle.Cms 命名空间:

public byte[] Encrypt(X509Certificate2 recipientCert)
{
    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");
    return outEncryptedStream;
}

错误堆栈跟踪:
KeyGenerator 2.16.840.1.101.3.4.1.46 not recognised.

您还提到了在C#中使用 AES256CBC 进行加密,然后在Java中可以解密。这可能是因为 AES256CBC 是一种常见的加密算法,两个平台都支持,因此可能导致您能够在两者之间进行交互解密。

为了使加密文件能够在C#和Java之间相互加解密,您可以尝试以下选项:
1. 确保在C#中和Java中使用相同的加密算法、密钥长度和模式。
2. 将加密和解密步骤分开,确保每个步骤的参数都正确匹配。
3. 检查加密算法的填充模式和其他参数是否相同。
4. 确保在C#和Java中使用相同的编码和字节顺序。
5. 在C#和Java中分别使用相同的库(例如 Bouncy Castle)来执行加密和解密操作,以确保一致性。

请注意,加密和解密之间的不匹配可能导致无法正确解密数据。确保在两个平台上使用相同的算法和参数是实现正确加解密的关键。
英文:

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?

答案1

得分: 1

抱歉,根据 https://github.com/bcgit/bc-csharp/blob/5bd4c8c70f80f1e7ead8e3c73459b78eb93d0ef7/crypto/src/security/GeneratorUtilities.cs 看起来即使在实际的C# Bouncy Castle中,AES-256-GCM模式也不可用:

static GeneratorUtilities()
...
AddKgAlgorithm("AES256",
  "2.16.840.1.101.3.4.42",
  NistObjectIdentifiers.IdAes256Cbc,
  NistObjectIdentifiers.IdAes256Cfb,
  NistObjectIdentifiers.IdAes256Ecb,
  NistObjectIdentifiers.IdAes256Ofb,
  NistObjectIdentifiers.IdAes256Wrap);
...
英文:

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

答案2

得分: 0

根据Michael Fehr的评论,C# Bouncy Castle中没有可用的AES-256-GCM模块,因此我们创建了Java API,并从我们的代码库中进行了调用。

英文:

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

huangapple
  • 本文由 发表于 2020年8月29日 17:41:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63645554.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定