Encryption C#BouncyCastle CMS开发密钥加密算法RSA-OAEP(SHA256,MGF1SHA256)
我正在为C#使用BouncyCastle(BC)API 在经历了几个小时的API地狱之后,我明白了如何使用CMS和BC进行签名/验证和加密/解密。 我必须使用RSA-OAEP(SHA256+MGF1和SHA256)作为密钥加密算法对CMSEDevelope的对称密钥进行加密。 默认情况下,BC显然使用RSA 在CMS信封的RecipientInfo结构中,我必须使用KeyTransRecipientInfo 我不知道如何将RSA OAEP算法设置为recipientInfo:Encryption C#BouncyCastle CMS开发密钥加密算法RSA-OAEP(SHA256,MGF1SHA256),encryption,cryptography,x509certificate,bouncycastle,envelope-schema,Encryption,Cryptography,X509certificate,Bouncycastle,Envelope Schema,我正在为C#使用BouncyCastle(BC)API 在经历了几个小时的API地狱之后,我明白了如何使用CMS和BC进行签名/验证和加密/解密。 我必须使用RSA-OAEP(SHA256+MGF1和SHA256)作为密钥加密算法对CMSEDevelope的对称密钥进行加密。 默认情况下,BC显然使用RSA 在CMS信封的RecipientInfo结构中,我必须使用KeyTransRecipientInfo 我不知道如何将RSA OAEP算法设置为recipientInfo: //Cre
//Create Encrypted cms envelope
X509Certificate otherscert = new X509CertificateParser().ReadCertificate(myCertBytes)
CmsEnvelopedDataGenerator envDataGen = new CmsEnvelopedDataGenerator();
envDataGen.AddKeyTransRecipient(othersCert); //setting Cert, but how the key encr. algorithm?
CmsProcessableByteArray sData = new CmsProcessableByteArray(signedData.GetEncoded());
var envData = envDataGen.Generate(sData, CmsEnvelopedDataGenerator.Aes256Cbc); //generate the envelope
现在在recipientInfo中,KeyEncryptionAlgOid是1.2.840.113549.1.1.1(RSA)
我需要它是1.2.840.113549.1.1.7(RSA-OAEP),带有提到的密钥加密参数
你知道如何在BC的C#API中做到这一点吗
编辑: 现在我从Git获得了源代码,并进行了以下编辑。 问题不仅仅是将keyEncryptionAlgorithm设置为收件人。 BC的逻辑采用证书主题PublicKeyInfo算法进行密钥加密 在cmsendevelopedGenerator.cs中,我添加了
public void AddKeyTransRecipientRsaOaep(
X509Certificate cert, DerObjectIdentifier digest, DerObjectIdentifier mgf1digest, AlgorithmIdentifier pSource = null)
{
if (pSource == null)
{
pSource = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]));
}
AlgorithmIdentifier hash = new AlgorithmIdentifier(digest, DerNull.Instance);
AlgorithmIdentifier mask = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, mgf1digest);
var rsaOaepParams = new RsaesOaepParameters(hash, mask, pSource);
KeyTransRecipientInfoGenerator ktrig = new KeyTransRecipientInfoGenerator();
ktrig.RecipientCert = cert;
ktrig.AlgorithmId = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdRsaesOaep, rsaOaepParams);
recipientInfoGenerators.Add(ktrig);
}
private AlgorithmIdentifier keyEncryptionAlg;
...
internal AlgorithmIdentifier AlgorithmId
{
set
{
keyEncryptionAlg = value;
}
}
...
protected virtual AlgorithmIdentifier AlgorithmDetails
{
get
{
if (keyEncryptionAlg == null)
{
return info.AlgorithmID;
}
else
{
return keyEncryptionAlg;
}
}
}
//In the Generate() method I changed
keyEncryptionAlgorithm = AlgorithmDetails;
//to
AlgorithmIdentifier keyEncryptionAlgorithm;
if (this.keyEncryptionAlg != null)
{
keyEncryptionAlgorithm = this.keyEncryptionAlg;
}
else
{
keyEncryptionAlgorithm = AlgorithmDetails;
}
在KeyTransrecipientInfoGenerator.cs中,我添加了
public void AddKeyTransRecipientRsaOaep(
X509Certificate cert, DerObjectIdentifier digest, DerObjectIdentifier mgf1digest, AlgorithmIdentifier pSource = null)
{
if (pSource == null)
{
pSource = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]));
}
AlgorithmIdentifier hash = new AlgorithmIdentifier(digest, DerNull.Instance);
AlgorithmIdentifier mask = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, mgf1digest);
var rsaOaepParams = new RsaesOaepParameters(hash, mask, pSource);
KeyTransRecipientInfoGenerator ktrig = new KeyTransRecipientInfoGenerator();
ktrig.RecipientCert = cert;
ktrig.AlgorithmId = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdRsaesOaep, rsaOaepParams);
recipientInfoGenerators.Add(ktrig);
}
private AlgorithmIdentifier keyEncryptionAlg;
...
internal AlgorithmIdentifier AlgorithmId
{
set
{
keyEncryptionAlg = value;
}
}
...
protected virtual AlgorithmIdentifier AlgorithmDetails
{
get
{
if (keyEncryptionAlg == null)
{
return info.AlgorithmID;
}
else
{
return keyEncryptionAlg;
}
}
}
//In the Generate() method I changed
keyEncryptionAlgorithm = AlgorithmDetails;
//to
AlgorithmIdentifier keyEncryptionAlgorithm;
if (this.keyEncryptionAlg != null)
{
keyEncryptionAlgorithm = this.keyEncryptionAlg;
}
else
{
keyEncryptionAlgorithm = AlgorithmDetails;
}
现在,keyEncryption算法和参数设置正确,加密无异常:
CmsEnvelopedDataGenerator envDataGen = new CmsEnvelopedDataGenerator();
envDataGen.AddKeyTransRecipientRsaOaep(othersCert, NistObjectIdentifiers.IdSha256, NistObjectIdentifiers.IdSha256);
CmsProcessableByteArray sData = new CmsProcessableByteArray(signedData.GetEncoded());
var envData = envDataGen.Generate(sData, CmsEnvelopedDataGenerator.Aes256Cbc);
使用BC或NetCore3读取信封效果良好。
RecipientInfos按预期设置(keyEncryptionAlgorithm,params)
但解密在两个上都失败:(GitHub针对同一问题的问题。由于C#和Java代码库的API和运行时通常是镜像的,Java也存在类似的问题(目前尚未解决)。是的,解密可能也需要更改代码。不幸的是,CMS和PGP功能都倾向于停留在过去。值得一提的是,.NET附带的EnvelopedCms类支持OAEP。@bartonjs所以有一部分.NET加密API比竞争库有更多的支持?这是罕见的,但cr我想,在应该编辑的地方编辑:)@bartonjs:for.NetCore仅从3.0开始。在我在netcore3.0中加密RSA-OAEP密钥后,至少有一个BC能够解密该密钥…;)。不幸的是,在网络中读取PEM文件是一团混乱。我将尝试Netcore 3.0/3.1中建议的代码调整,使用rsaes-oaep-Sha256加密私钥工作正常,但未实现解密。仅实现了rsaes-oaep-Sha1。所以现在我只能用netCore 3.0加密,只能用BouncyCastle解密。。。搞什么鬼。