英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论