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

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

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

问题

  1. 我试图在C#中部分成功地复制了一个Java示例,以下是代码部分:
  2. Java示例:
  3. CMSEnvelopedDataStreamGenerator gen = new CMSEnvelopedDataStreamGenerator();
  4. gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(remoteEncryptionCert, rsaesOaepIdentifier()));
  5. OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_GCM).setProvider(BC).build();
  6. try (FileOutputStream fileStream = new FileOutputStream(OUTPUT_FILE); OutputStream encryptingOutputStream = gen.open(fileStream, encryptor)) {
  7. // 写入文件
  8. encryptingOutputStream.flush();
  9. }
  10. C#尝试:
  11. 使用 System.Security.Cryptography.Pkcs 命名空间:
  12. public byte[] Encrypt(byte[] plainBytes, X509Certificate2 recipientCert)
  13. {
  14. ContentInfo plainContent = new ContentInfo(plainBytes);
  15. Oid encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.46"); // AES-256-GCM
  16. EnvelopedCms encryptedData = new EnvelopedCms(plainContent, new AlgorithmIdentifier(encryptAlgoOid));
  17. CmsRecipient recipient = new CmsRecipient(recipientCert);
  18. encryptedData.Encrypt(recipient);
  19. byte[] encryptedBytes = encryptedData.Encode();
  20. return encryptedBytes;
  21. }
  22. 错误堆栈跟踪:
  23. Unknown cryptographic algorithm.
  24. 使用 Org.BouncyCastle.Cms 命名空间:
  25. public byte[] Encrypt(X509Certificate2 recipientCert)
  26. {
  27. FileStream fileEncrypted = new FileStream(pathToFile);
  28. CmsEnvelopedDataStreamGenerator gen = new CmsEnvelopedDataStreamGenerator();
  29. gen.AddKeyTransRecipient(recipientCert);
  30. var outEncryptedStream = gen.Open(fileEncrypted, "2.16.840.1.101.3.4.1.46");
  31. return outEncryptedStream;
  32. }
  33. 错误堆栈跟踪:
  34. KeyGenerator 2.16.840.1.101.3.4.1.46 not recognised.
  35. 您还提到了在C#中使用 AES256CBC 进行加密,然后在Java中可以解密。这可能是因为 AES256CBC 是一种常见的加密算法,两个平台都支持,因此可能导致您能够在两者之间进行交互解密。
  36. 为了使加密文件能够在C#和Java之间相互加解密,您可以尝试以下选项:
  37. 1. 确保在C#中和Java中使用相同的加密算法、密钥长度和模式。
  38. 2. 将加密和解密步骤分开,确保每个步骤的参数都正确匹配。
  39. 3. 检查加密算法的填充模式和其他参数是否相同。
  40. 4. 确保在C#和Java中使用相同的编码和字节顺序。
  41. 5. C#和Java中分别使用相同的库(例如 Bouncy Castle)来执行加密和解密操作,以确保一致性。
  42. 请注意,加密和解密之间的不匹配可能导致无法正确解密数据。确保在两个平台上使用相同的算法和参数是实现正确加解密的关键。
英文:

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

  1. CMSEnvelopedDataStreamGenerator gen = new CMSEnvelopedDataStreamGenerator();
  2. // NOTE: Uses the RECEIVER's PUBLIC encryption key
  3. gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(remoteEncryptionCert, rsaesOaepIdentifier()));
  4. OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_GCM).setProvider(BC).build();
  5. try (FileOutputStream fileStream = new FileOutputStream(OUTPUT_FILE); OutputStream encryptingOutputStream = gen.open(fileStream, encryptor)) {
  6. //
  7. // write file
  8. //
  9. encryptingOutputStream.flush();
  10. }

I've tried so far

Using System.Security.Cryptography.Pkcs

  1. public byte[] Encrypt(byte[] plainBytes, X509Certificate2 recipientCert)
  2. {
  3. // create ContentInfo
  4. ContentInfo plainContent = new ContentInfo(plainBytes);
  5. // EnvelopedCms represents encrypted data
  6. Oid encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.46"); // AES-256-GCM,
  7. //Oid encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.42"); // AES-256-CBC
  8. EnvelopedCms encryptedData = new EnvelopedCms(plainContent, new AlgorithmIdentifier(encryptAlgoOid));
  9. // add a recipient
  10. CmsRecipient recipient = new CmsRecipient(recipientCert);
  11. // encrypt data with public key of recipient
  12. encryptedData.Encrypt(recipient); //Throws "Unknown cryptographic algorithm."
  13. // create PKCS #7 byte array
  14. byte[] encryptedBytes = encryptedData.Encode();
  15. // return encrypted data
  16. return encryptedBytes;
  17. }

error stack trace

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

Using Org.BouncyCastle.Cms

  1. public byte[] Encrypt(X509Certificate2 recipientCert)
  2. {
  3. // file stream
  4. FileStream fileEncrypted = new FileStream(pathToFile)
  5. CmsEnvelopedDataStreamGenerator gen = new CmsEnvelopedDataStreamGenerator();
  6. gen.AddKeyTransRecipient(recipientCert);
  7. var outEncryptedStream = gen.Open(fileEncrypted, "2.16.840.1.101.3.4.1.46");
  8. // Throws "KeyGenerator 2.16.840.1.101.3.4.1.46 not recognised." CmsEnvelopedDataGenerator doesn't
  9. // have named constant for aes256gcm
  10. return outEncryptedStream
  11. }

error stack trace

  1. KeyGenerator 2.16.840.1.101.3.4.1.46 not recognised.
  2. at Org.BouncyCastle.Security.GeneratorUtilities.GetKeyGenerator(String algorithm)
  3. at Org.BouncyCastle.Cms.CmsEnvelopedDataStreamGenerator.Open(Stream outStream, String encryptionOid)
  4. 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模式也不可用:

  1. static GeneratorUtilities()
  2. ...
  3. AddKgAlgorithm("AES256",
  4. "2.16.840.1.101.3.4.42",
  5. NistObjectIdentifiers.IdAes256Cbc,
  6. NistObjectIdentifiers.IdAes256Cfb,
  7. NistObjectIdentifiers.IdAes256Ecb,
  8. NistObjectIdentifiers.IdAes256Ofb,
  9. NistObjectIdentifiers.IdAes256Wrap);
  10. ...
英文:

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:

  1. static GeneratorUtilities()
  2. ...
  3. AddKgAlgorithm("AES256",
  4. "2.16.840.1.101.3.4.42",
  5. NistObjectIdentifiers.IdAes256Cbc,
  6. NistObjectIdentifiers.IdAes256Cfb,
  7. NistObjectIdentifiers.IdAes256Ecb,
  8. NistObjectIdentifiers.IdAes256Ofb,
  9. NistObjectIdentifiers.IdAes256Wrap);
  10. ...

答案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:

确定