Encryption C#BouncyCastle CMS开发密钥加密算法RSA-OAEP(SHA256,MGF1SHA256)

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

我正在为C#使用BouncyCastle(BC)API

在经历了几个小时的API地狱之后,我明白了如何使用CMS和BC进行签名/验证和加密/解密。 我必须使用RSA-OAEP(SHA256+MGF1和SHA256)作为密钥加密算法对CMSEDevelope的对称密钥进行加密。 默认情况下,BC显然使用RSA

在CMS信封的RecipientInfo结构中,我必须使用KeyTransRecipientInfo

我不知道如何将RSA OAEP算法设置为recipientInfo:

    //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解密。。。搞什么鬼。