【问题标题】:Problem with encrypt/decrypting files using aes256gcm algorithm in envelopedCms. What are mine options?在envelopeCms 中使用aes256gcm 算法加密/解密文件的问题。我的选择是什么?
【发布时间】:2020-12-18 01:58:53
【问题描述】:

我正在尝试在 c# 中复制 Java 中的示例并取得部分成功

    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();
            }

我已经试过了

使用 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;
}

错误堆栈跟踪

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

使用 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
}

错误堆栈跟踪

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

我必须让它以某种方式工作,以便我可以使用 c# 代码加密文件并使用 java 解密,反之亦然。

我注意到如果我在 c# 中使用 Aes256CBC 加密文件,我可以在 java 中解密它,这怎么可能?这是否意味着我实施了错误的加密?

那么我有哪些选择来完成这项工作?

【问题讨论】:

  • java和c#中默认的padding选项不同。所以你必须在 c# 中指定填充。
  • 好的,这可能是另一个问题,但我什至无法使用 AES256GCM 算法完成加密
  • 如果填充错误,你会得到一个异常。加密类能够确定错误的输入(与参数设置不匹配的输入)。请参阅:stackoverflow.com/questions/21890805/…
  • 加密类有很多不同的参数设置。加密和解密需要使用完全相同的参数
  • 您在使用 AES256GCM 时遇到异常 - 嗯,让我想想它是 100 多个异常中的哪一个......如果没有完整的错误堆栈跟踪和要点(行代码)它指向。所以请编辑您的帖子并添加堆栈跟踪,谢谢。

标签: java c# encryption aes-gcm


【解决方案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);
...

【讨论】:

  • 我知道,但我的选择是什么?还有其他我可以使用的库吗?
【解决方案2】:

根据Michael Fehr 评论 AES-256-GCM 模块在 C# Bouncy Castle 中不可用,因此我们制作了 Java Api 并从我们的代码库中调用

【讨论】:

    猜你喜欢
    • 2011-10-13
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多