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