예제 #1
0
        public static Asn1EncodableVector GenerateSignerInfo(X509Certificate2 cert,
                                                             String digestAlgorithmName,
                                                             byte[] datos,
                                                             AdESPolicy policy,
                                                             bool signingCertificateV2,
                                                             byte[] messageDigest,
                                                             DateTime signDate,
                                                             bool padesMode,
                                                             String contentType,
                                                             String contentDescription)
        {
            // ALGORITMO DE HUELLA DIGITAL
            AlgorithmIdentifier digestAlgorithmOID = SigUtils.MakeAlgId(AOAlgorithmID.GetOID(digestAlgorithmName));

            // // ATRIBUTOS

            // authenticatedAttributes
            Asn1EncodableVector contexExpecific = InitContexExpecific(
                digestAlgorithmName,
                datos,
                Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.Data.Id,
                messageDigest,
                signDate,
                padesMode
                );

            // Serial Number
            // comentar lo de abajo para version del rfc 3852

            if (signingCertificateV2)
            {
                // INICIO SINGING CERTIFICATE-V2

                /** IssuerSerial ::= SEQUENCE { issuer GeneralNames, serialNumber
                 * CertificateSerialNumber */



                TbsCertificateStructure tbs = TbsCertificateStructure.GetInstance(
                    Asn1Object.FromByteArray(
                        new Org.BouncyCastle.X509.X509Certificate(
                            X509CertificateStructure.GetInstance(
                                Asn1Object.FromByteArray(
                                    cert.GetRawCertData()))).GetTbsCertificate()));

                GeneralNames gns = new GeneralNames(new GeneralName(tbs.Issuer));

                IssuerSerial isuerSerial = new IssuerSerial(gns, tbs.SerialNumber);

                /** ESSCertIDv2 ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier
                 * DEFAULT {algorithm id-sha256}, certHash Hash, issuerSerial
                 * IssuerSerial OPTIONAL }
                 * Hash ::= OCTET STRING */

                byte[]        certHash    = Digester.Digest(cert.GetRawCertData(), digestAlgorithmName);
                EssCertIDv2[] essCertIDv2 = { new EssCertIDv2(digestAlgorithmOID, certHash, isuerSerial) };

                /** PolicyInformation ::= SEQUENCE { policyIdentifier CertPolicyId,
                 * policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo
                 * OPTIONAL }
                 * CertPolicyId ::= OBJECT IDENTIFIER
                 * PolicyQualifierInfo ::= SEQUENCE { policyQualifierId
                 * PolicyQualifierId, qualifier ANY DEFINED BY policyQualifierId } */

                SigningCertificateV2 scv2;
                if (policy.GetPolicyIdentifier() != null)
                {
                    /** SigningCertificateV2 ::= SEQUENCE { certs SEQUENCE OF
                     * ESSCertIDv2, policies SEQUENCE OF PolicyInformation OPTIONAL
                     * } */
                    scv2 = new SigningCertificateV2(essCertIDv2, GetPolicyInformation(policy)); // con politica
                }
                else
                {
                    scv2 = new SigningCertificateV2(essCertIDv2); // Sin politica
                }

                // Secuencia con singningCertificate
                contexExpecific.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.IdAASigningCertificateV2, new DerSet(scv2)));

                // FIN SINGING CERTIFICATE-V2
            }
            else
            {
                // INICIO SINGNING CERTIFICATE

                /** IssuerSerial ::= SEQUENCE { issuer GeneralNames, serialNumber
                 * CertificateSerialNumber } */

                TbsCertificateStructure tbs = TbsCertificateStructure.GetInstance(
                    Asn1Object.FromByteArray(
                        new Org.BouncyCastle.X509.X509Certificate(
                            X509CertificateStructure.GetInstance(
                                Asn1Object.FromByteArray(
                                    cert.GetRawCertData()))).GetTbsCertificate()));

                GeneralName  gn  = new GeneralName(tbs.Issuer);
                GeneralNames gns = new GeneralNames(gn);

                IssuerSerial isuerSerial = new IssuerSerial(gns, tbs.SerialNumber);

                /** ESSCertID ::= SEQUENCE { certHash Hash, issuerSerial IssuerSerial
                 * OPTIONAL }
                 * Hash ::= OCTET STRING -- SHA1 hash of entire certificate */
                byte[] certHash = Digester.Digest(cert.GetRawCertData(), digestAlgorithmName);

                EssCertID essCertID = new EssCertID(certHash, isuerSerial);

                /** PolicyInformation ::= SEQUENCE { policyIdentifier CertPolicyId,
                 * policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo
                 * OPTIONAL }
                 * CertPolicyId ::= OBJECT IDENTIFIER
                 * PolicyQualifierInfo ::= SEQUENCE { policyQualifierId
                 * PolicyQualifierId, qualifier ANY DEFINED BY policyQualifierId } */

                SigningCertificate scv;
                if (policy.GetPolicyIdentifier() != null)
                {
                    /** SigningCertificateV2 ::= SEQUENCE { certs SEQUENCE OF
                     * ESSCertIDv2, policies SEQUENCE OF PolicyInformation OPTIONAL
                     * } */
                    /*
                     * HAY QUE HACER UN SEQUENCE, YA QUE EL CONSTRUCTOR DE BOUNCY
                     * CASTLE NO TIENE DICHO CONSTRUCTOR.
                     */
                    Asn1EncodableVector v = new Asn1EncodableVector();
                    v.Add(new DerSequence(essCertID));
                    v.Add(new DerSequence(GetPolicyInformation(policy)));
                    scv = SigningCertificate.GetInstance(new DerSequence(v)); // con politica
                }
                else
                {
                    scv = new SigningCertificate(essCertID); // Sin politica
                }

                /** id-aa-signingCertificate OBJECT IDENTIFIER ::= { iso(1)
                 * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16)
                 * id-aa(2) 12 } */
                // Secuencia con singningCertificate
                contexExpecific.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.IdAASigningCertificate, new DerSet(scv)));
            }

            // INICIO SIGPOLICYID ATTRIBUTE

            if (policy.GetPolicyIdentifier() != null)
            {
                /**
                 * SigPolicyId ::= OBJECT IDENTIFIER Politica de firma.
                 */
                DerObjectIdentifier doiSigPolicyId = new DerObjectIdentifier(policy.GetPolicyIdentifier().ToLower().Replace("urn:oid:", ""));

                /**
                 *   OtherHashAlgAndValue ::= SEQUENCE {
                 *     hashAlgorithm    AlgorithmIdentifier,
                 *     hashValue        OCTET STRING }
                 *
                 */


                // Algoritmo para el hash
                AlgorithmIdentifier hashid;
                // si tenemos algoritmo de calculo de hash, lo ponemos
                if (policy.GetPolicyIdentifierHashAlgorithm() != null)
                {
                    hashid = SigUtils.MakeAlgId(
                        AOAlgorithmID.GetOID(
                            AOSignConstants.GetDigestAlgorithmName(
                                policy.GetPolicyIdentifierHashAlgorithm())));
                }
                // si no tenemos, ponemos el algoritmo de firma.
                else
                {
                    hashid = digestAlgorithmOID;
                }
                // hash del documento, descifrado en b64
                byte[] hashed;
                if (policy.GetPolicyIdentifierHash() != null)
                {
                    hashed = System.Convert.FromBase64String(policy.GetPolicyIdentifierHash());
                }
                else
                {
                    hashed = new byte[] { 0 };
                }

                DigestInfo otherHashAlgAndValue = new DigestInfo(hashid, hashed);

                /**
                 *   SigPolicyQualifierInfo ::= SEQUENCE {
                 *       SigPolicyQualifierId  SigPolicyQualifierId,
                 *       SigQualifier          ANY DEFINED BY policyQualifierId }
                 */

                AOSigPolicyQualifierInfo spqInfo = null;
                if (policy.GetPolicyQualifier() != null)
                {
                    spqInfo = new AOSigPolicyQualifierInfo(policy.GetPolicyQualifier().ToString());
                }

                /**
                 * SignaturePolicyId ::= SEQUENCE {
                 *  sigPolicyId           SigPolicyId,
                 *  sigPolicyHash         SigPolicyHash,
                 *  sigPolicyQualifiers   SEQUENCE SIZE (1..MAX) OF
                 *                          AOSigPolicyQualifierInfo OPTIONAL}
                 *
                 */
                Asn1EncodableVector v = new Asn1EncodableVector();
                // sigPolicyId
                v.Add(doiSigPolicyId);
                // sigPolicyHash
                v.Add(otherHashAlgAndValue.ToAsn1Object()); // como sequence
                // sigPolicyQualifiers
                if (spqInfo != null)
                {
                    v.Add(spqInfo.toASN1Primitive());
                }

                DerSequence ds = new DerSequence(v);

                // Secuencia con singningCertificate
                contexExpecific.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.IdAAEtsSigPolicyID, new DerSet(ds.ToAsn1Object())));
                // FIN SIGPOLICYID ATTRIBUTE
            }

            /**
             * Secuencia con el tipo de contenido firmado. No se agrega en firmas PAdES.
             *
             * ContentHints ::= SEQUENCE {
             *	  contentDescription UTF8String (SIZE (1..MAX)) OPTIONAL,
             *	  contentType ContentType }
             */
            if (contentType != null && !padesMode)
            {
                ContentHints contentHints;
                if (contentDescription != null)
                {
                    contentHints = new ContentHints(new DerObjectIdentifier(contentType),
                                                    new DerUtf8String(contentDescription));
                }
                else
                {
                    contentHints = new ContentHints(new DerObjectIdentifier(contentType));
                }
                contexExpecific.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(
                                        Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.IdAAContentHint,
                                        new DerSet(contentHints.ToAsn1Object())));
            }

            return(contexExpecific);
        }
예제 #2
0
            internal RecipientInfo ToRecipientInfo(
                KeyParameter key,
                SecureRandom random)
            {
                byte[] keyBytes = key.GetKey();

                if (pubKey != null)
                {
                    IWrapper keyWrapper = Helper.CreateWrapper(keyEncAlg.ObjectID.Id);

                    keyWrapper.Init(true, new ParametersWithRandom(pubKey, random));

                    Asn1OctetString encKey = new DerOctetString(
                        keyWrapper.Wrap(keyBytes, 0, keyBytes.Length));

                    RecipientIdentifier recipId;
                    if (cert != null)
                    {
                        TbsCertificateStructure tbs = TbsCertificateStructure.GetInstance(
                            Asn1Object.FromByteArray(cert.GetTbsCertificate()));

                        Asn1.Cms.IssuerAndSerialNumber encSid = new Asn1.Cms.IssuerAndSerialNumber(
                            tbs.Issuer, tbs.SerialNumber.Value);

                        recipId = new RecipientIdentifier(encSid);
                    }
                    else
                    {
                        recipId = new RecipientIdentifier(subKeyId);
                    }

                    return(new RecipientInfo(new KeyTransRecipientInfo(recipId, keyEncAlg, encKey)));
                }
                else if (originator != null)
                {
                    IWrapper keyWrapper = Helper.CreateWrapper(
                        DerObjectIdentifier.GetInstance(
                            Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id);

                    keyWrapper.Init(true, new ParametersWithRandom(secKey, random));

                    Asn1OctetString encKey = new DerOctetString(
                        keyWrapper.Wrap(keyBytes, 0, keyBytes.Length));

                    RecipientEncryptedKey rKey = new RecipientEncryptedKey(
                        new KeyAgreeRecipientIdentifier(
                            new Asn1.Cms.IssuerAndSerialNumber(
                                PrincipalUtilities.GetIssuerX509Principal(cert),
                                cert.SerialNumber)),
                        encKey);

                    return(new RecipientInfo(
                               new KeyAgreeRecipientInfo(originator, ukm, keyEncAlg, new DerSequence(rKey))));
                }
                else if (derivationAlg != null)
                {
                    string   rfc3211WrapperName = Helper.GetRfc3211WrapperName(secKeyAlgorithm);
                    IWrapper keyWrapper         = Helper.CreateWrapper(rfc3211WrapperName);


                    // Note: In Java build, the IV is automatically generated in JCE layer
                    int    ivLength = rfc3211WrapperName.StartsWith("DESEDE") ? 8 : 16;
                    byte[] iv       = new byte[ivLength];
                    random.NextBytes(iv);


                    ICipherParameters parameters = new ParametersWithIV(secKey, iv);
                    keyWrapper.Init(true, new ParametersWithRandom(parameters, random));

                    Asn1OctetString encKey = new DerOctetString(
                        keyWrapper.Wrap(keyBytes, 0, keyBytes.Length));

//					byte[] iv = keyWrapper.GetIV();

                    DerSequence seq = new DerSequence(
                        new DerObjectIdentifier(secKeyAlgorithm),
                        new DerOctetString(iv));

                    keyEncAlg = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgPwriKek, seq);

                    return(new RecipientInfo(new PasswordRecipientInfo(derivationAlg, keyEncAlg, encKey)));
                }
                else
                {
                    IWrapper keyWrapper = Helper.CreateWrapper(keyEncAlg.ObjectID.Id);

                    keyWrapper.Init(true, new ParametersWithRandom(secKey, random));

                    Asn1OctetString encKey = new DerOctetString(
                        keyWrapper.Wrap(keyBytes, 0, keyBytes.Length));

                    return(new RecipientInfo(new KekRecipientInfo(secKeyId, keyEncAlg, encKey)));
                }
            }
예제 #3
0
    public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
    {
        byte[] key = contentEncryptionKey.GetKey();
        AsymmetricKeyParameter    @public          = senderKeyPair.Public;
        ICipherParameters         cipherParameters = senderKeyPair.Private;
        OriginatorIdentifierOrKey originator;

        try
        {
            originator = new OriginatorIdentifierOrKey(CreateOriginatorPublicKey(@public));
        }
        catch (IOException arg)
        {
            throw new InvalidKeyException("cannot extract originator public key: " + arg);
        }
        Asn1OctetString ukm = null;

        if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
        {
            try
            {
                IAsymmetricCipherKeyPairGenerator keyPairGenerator = GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID);
                keyPairGenerator.Init(((ECPublicKeyParameters)@public).CreateKeyGenerationParameters(random));
                AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.GenerateKeyPair();
                ukm = new DerOctetString(new MQVuserKeyingMaterial(CreateOriginatorPublicKey(asymmetricCipherKeyPair.Public), null));
                cipherParameters = new MqvPrivateParameters((ECPrivateKeyParameters)cipherParameters, (ECPrivateKeyParameters)asymmetricCipherKeyPair.Private, (ECPublicKeyParameters)asymmetricCipherKeyPair.Public);
            }
            catch (IOException arg2)
            {
                throw new InvalidKeyException("cannot extract MQV ephemeral public key: " + arg2);
            }
            catch (SecurityUtilityException arg3)
            {
                throw new InvalidKeyException("cannot determine MQV ephemeral key pair parameters from public key: " + arg3);
            }
        }
        DerSequence         parameters             = new DerSequence(keyEncryptionOID, DerNull.Instance);
        AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(keyAgreementOID, parameters);
        Asn1EncodableVector asn1EncodableVector    = new Asn1EncodableVector();

        foreach (X509Certificate recipientCert in recipientCerts)
        {
            TbsCertificateStructure instance;
            try
            {
                instance = TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(recipientCert.GetTbsCertificate()));
            }
            catch (Exception)
            {
                throw new ArgumentException("can't extract TBS structure from certificate");
            }
            IssuerAndSerialNumber       issuerSerial      = new IssuerAndSerialNumber(instance.Issuer, instance.SerialNumber.Value);
            KeyAgreeRecipientIdentifier id                = new KeyAgreeRecipientIdentifier(issuerSerial);
            ICipherParameters           cipherParameters2 = recipientCert.GetPublicKey();
            if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
            {
                cipherParameters2 = new MqvPublicParameters((ECPublicKeyParameters)cipherParameters2, (ECPublicKeyParameters)cipherParameters2);
            }
            IBasicAgreement basicAgreementWithKdf = AgreementUtilities.GetBasicAgreementWithKdf(keyAgreementOID, keyEncryptionOID.Id);
            basicAgreementWithKdf.Init(new ParametersWithRandom(cipherParameters, random));
            BigInteger   s           = basicAgreementWithKdf.CalculateAgreement(cipherParameters2);
            int          qLength     = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8;
            byte[]       keyBytes    = X9IntegerConverter.IntegerToBytes(s, qLength);
            KeyParameter parameters2 = ParameterUtilities.CreateKeyParameter(keyEncryptionOID, keyBytes);
            IWrapper     wrapper     = Helper.CreateWrapper(keyEncryptionOID.Id);
            wrapper.Init(forWrapping: true, new ParametersWithRandom(parameters2, random));
            byte[]          str          = wrapper.Wrap(key, 0, key.Length);
            Asn1OctetString encryptedKey = new DerOctetString(str);
            asn1EncodableVector.Add(new RecipientEncryptedKey(id, encryptedKey));
        }
        return(new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncryptionAlgorithm, new DerSequence(asn1EncodableVector))));
    }
예제 #4
0
파일: CMSUtils.cs 프로젝트: 894880010/MP
 internal static TbsCertificateStructure GetTbsCertificateStructure(X509Certificate cert)
 {
     return(TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetTbsCertificate())));
 }
            internal SignerInfo ToSignerInfo(
                DerObjectIdentifier contentType)
            {
                AlgorithmIdentifier digAlgId = new AlgorithmIdentifier(
                    new DerObjectIdentifier(this._digestOID), DerNull.Instance);
                AlgorithmIdentifier encAlgId = CmsSignedGenerator.GetEncAlgorithmIdentifier(this.EncryptionAlgOid);

                byte[] hash = (byte[])outer._messageHashes[Helper.GetDigestAlgName(this._digestOID)];

                outer._digests[_digestOID] = hash.Clone();

                IDictionary parameters = outer.GetBaseParameters(contentType, digAlgId, hash);

                Asn1.Cms.AttributeTable signed = (_sAttr != null)
//					?	_sAttr.GetAttributes(Collections.unmodifiableMap(parameters))
                                        ?       _sAttr.GetAttributes(parameters)
                                        :       null;

                Asn1Set signedAttr = outer.GetAttributeSet(signed);

                //
                // sig must be composed from the DER encoding.
                //
                byte[] tmp;
                if (signedAttr != null)
                {
                    tmp = signedAttr.GetEncoded(Asn1Encodable.Der);
                }
                else
                {
                    throw new Exception("signatures without signed attributes not implemented.");
                }

                _signature.BlockUpdate(tmp, 0, tmp.Length);

                Asn1OctetString encDigest = new DerOctetString(_signature.GenerateSignature());

                parameters = outer.GetBaseParameters(contentType, digAlgId, hash);
                parameters[CmsAttributeTableParameter.Signature] = encDigest.GetOctets().Clone();

                Asn1.Cms.AttributeTable unsigned = (_unsAttr != null)
//					?	_unsAttr.getAttributes(Collections.unmodifiableMap(parameters))
                                        ?       _unsAttr.GetAttributes(parameters)
                                        :       null;

                Asn1Set unsignedAttr = outer.GetAttributeSet(unsigned);

                X509Certificate  cert = this.Certificate;
                SignerIdentifier signerIdentifier;

                if (cert != null)
                {
                    TbsCertificateStructure tbs = TbsCertificateStructure.GetInstance(
                        Asn1Object.FromByteArray(cert.GetTbsCertificate()));
                    IssuerAndSerialNumber encSid = new IssuerAndSerialNumber(
                        tbs.Issuer, tbs.SerialNumber.Value);

                    signerIdentifier = new SignerIdentifier(encSid);
                }
                else
                {
                    signerIdentifier = new SignerIdentifier(new DerOctetString(_subjectKeyID));
                }

                return(new SignerInfo(signerIdentifier, digAlgId,
                                      signedAttr, encAlgId, encDigest, unsignedAttr));
            }
예제 #6
0
        public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
        {
            byte[] keyBytes = contentEncryptionKey.GetKey();

            AsymmetricKeyParameter senderPublicKey     = senderKeyPair.Public;
            ICipherParameters      senderPrivateParams = senderKeyPair.Private;


            OriginatorIdentifierOrKey originator;

            try
            {
                originator = new OriginatorIdentifierOrKey(
                    CreateOriginatorPublicKey(senderPublicKey));
            }
            catch (IOException e)
            {
                throw new InvalidKeyException("cannot extract originator public key: " + e);
            }


            Asn1OctetString ukm = null;

            if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
            {
                try
                {
                    IAsymmetricCipherKeyPairGenerator ephemKPG =
                        GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID);
                    ephemKPG.Init(
                        ((ECPublicKeyParameters)senderPublicKey).CreateKeyGenerationParameters(random));

                    AsymmetricCipherKeyPair ephemKP = ephemKPG.GenerateKeyPair();

                    ukm = new DerOctetString(
                        new MQVuserKeyingMaterial(
                            CreateOriginatorPublicKey(ephemKP.Public), null));

                    senderPrivateParams = new MqvPrivateParameters(
                        (ECPrivateKeyParameters)senderPrivateParams,
                        (ECPrivateKeyParameters)ephemKP.Private,
                        (ECPublicKeyParameters)ephemKP.Public);
                }
                catch (IOException e)
                {
                    throw new InvalidKeyException("cannot extract MQV ephemeral public key: " + e);
                }
                catch (SecurityUtilityException e)
                {
                    throw new InvalidKeyException("cannot determine MQV ephemeral key pair parameters from public key: " + e);
                }
            }


            DerSequence paramSeq = new DerSequence(
                keyEncryptionOID,
                DerNull.Instance);
            AlgorithmIdentifier keyEncAlg = new AlgorithmIdentifier(keyAgreementOID, paramSeq);


            Asn1EncodableVector recipientEncryptedKeys = new Asn1EncodableVector();

            foreach (X509Certificate recipientCert in recipientCerts)
            {
                TbsCertificateStructure tbsCert;
                try
                {
                    tbsCert = TbsCertificateStructure.GetInstance(
                        Asn1Object.FromByteArray(recipientCert.GetTbsCertificate()));
                }
                catch (Exception)
                {
                    throw new ArgumentException("can't extract TBS structure from certificate");
                }

                // TODO Should there be a SubjectKeyIdentifier-based alternative?
                IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(
                    tbsCert.Issuer, tbsCert.SerialNumber.Value);
                KeyAgreeRecipientIdentifier karid = new KeyAgreeRecipientIdentifier(issuerSerial);

                ICipherParameters recipientPublicParams = recipientCert.GetPublicKey();
                if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
                {
                    recipientPublicParams = new MqvPublicParameters(
                        (ECPublicKeyParameters)recipientPublicParams,
                        (ECPublicKeyParameters)recipientPublicParams);
                }

                // Use key agreement to choose a wrap key for this recipient
                IBasicAgreement keyAgreement = AgreementUtilities.GetBasicAgreementWithKdf(
                    keyAgreementOID, keyEncryptionOID.Id);
                keyAgreement.Init(new ParametersWithRandom(senderPrivateParams, random));
                BigInteger agreedValue = keyAgreement.CalculateAgreement(recipientPublicParams);

                int          keyEncryptionKeySize  = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8;
                byte[]       keyEncryptionKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, keyEncryptionKeySize);
                KeyParameter keyEncryptionKey      = ParameterUtilities.CreateKeyParameter(
                    keyEncryptionOID, keyEncryptionKeyBytes);

                // Wrap the content encryption key with the agreement key
                IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionOID.Id);
                keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random));
                byte[] encryptedKeyBytes = keyWrapper.Wrap(keyBytes, 0, keyBytes.Length);

                Asn1OctetString encryptedKey = new DerOctetString(encryptedKeyBytes);

                recipientEncryptedKeys.Add(new RecipientEncryptedKey(karid, encryptedKey));
            }

            return(new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncAlg,
                                                               new DerSequence(recipientEncryptedKeys))));
        }
            internal Asn1.Cms.SignerInfo ToSignerInfo(
                DerObjectIdentifier contentType,
                CmsProcessable content)
            {
                AlgorithmIdentifier digAlgId = new AlgorithmIdentifier(
                    new DerObjectIdentifier(this.DigestAlgOid), DerNull.Instance);
                AlgorithmIdentifier encAlgId = CmsSignedGenerator.GetEncAlgorithmIdentifier(this.EncryptionAlgOid);
                string  digestName           = Helper.GetDigestAlgName(digestOID);
                string  signatureName        = digestName + "with" + Helper.GetEncryptionAlgName(encOID);
                ISigner sig = Helper.GetSignatureInstance(signatureName);
                IDigest dig = Helper.GetDigestInstance(digestName);

                byte[] hash = null;

                if (content != null)
                {
                    content.Write(new DigOutputStream(dig));

                    hash = DigestUtilities.DoFinal(dig);

                    outer._digests.Add(digestOID, hash.Clone());
                }

                IDictionary parameters = outer.GetBaseParameters(contentType, digAlgId, hash);

                Asn1.Cms.AttributeTable signed = (sAttr != null)
//					?	sAttr.GetAttributes(Collections.unmodifiableMap(parameters))
                                        ?       sAttr.GetAttributes(parameters)
                                        :       null;

                Asn1Set signedAttr = outer.GetAttributeSet(signed);


                //
                // sig must be composed from the DER encoding.
                //
                byte[] tmp;
                if (signedAttr != null)
                {
                    tmp = signedAttr.GetDerEncoded();
                }
                else
                {
                    MemoryStream bOut = new MemoryStream();
                    content.Write(bOut);
                    tmp = bOut.ToArray();
                }

                sig.Init(true, key);
                sig.BlockUpdate(tmp, 0, tmp.Length);

                Asn1OctetString encDigest = new DerOctetString(sig.GenerateSignature());

                IDictionary baseParameters = outer.GetBaseParameters(contentType, digAlgId, hash);

                baseParameters[CmsAttributeTableParameter.Signature] = encDigest.GetOctets().Clone();

                Asn1.Cms.AttributeTable unsigned = (unsAttr != null)
//					?	unsAttr.GetAttributes(Collections.unmodifiableMap(baseParameters))
                                        ?       unsAttr.GetAttributes(baseParameters)
                                        :       null;

                Asn1Set unsignedAttr = outer.GetAttributeSet(unsigned);

                X509Certificate         cert = this.GetCertificate();
                TbsCertificateStructure tbs  = TbsCertificateStructure.GetInstance(
                    Asn1Object.FromByteArray(cert.GetTbsCertificate()));

                Asn1.Cms.IssuerAndSerialNumber encSid = new Asn1.Cms.IssuerAndSerialNumber(
                    tbs.Issuer, tbs.SerialNumber.Value);

                return(new Asn1.Cms.SignerInfo(new SignerIdentifier(encSid), digAlgId,
                                               signedAttr, encAlgId, encDigest, unsignedAttr));
            }
        public static byte[] PostSign(String digestAlgorithmName,
                                      byte[] content,
                                      X509Certificate2[] signerCertificateChain,
                                      byte[] signature,
                                      byte[] signedAttributes)
        {
            if (signerCertificateChain == null || signerCertificateChain.Length == 0)
            {
                throw new ArgumentException("La cadena de certificados debe contener al menos una entrada");
            }

            TbsCertificateStructure tbsCertificateStructure;

            //TODO Revisar esta parte del código

            /**
             *
             *  Revisar esta parte del código
             *
             */
            tbsCertificateStructure = TbsCertificateStructure.GetInstance(
                Asn1Object.FromByteArray(
                    new Org.BouncyCastle.X509.X509Certificate(
                        X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(signerCertificateChain[0].GetRawCertData()))).GetTbsCertificate()
                    )
                );

            SignerIdentifier signerIdentifier = new SignerIdentifier(
                new IssuerAndSerialNumber(X509Name.GetInstance(tbsCertificateStructure.Issuer), tbsCertificateStructure.SerialNumber)
                );

            // Algoritmo de huella digital
            AlgorithmIdentifier digestAlgorithmOID;

            digestAlgorithmOID = SigUtils.MakeAlgId(AOAlgorithmID.GetOID(digestAlgorithmName));

            // EncryptionAlgorithm
            AlgorithmIdentifier keyAlgorithmIdentifier;

            keyAlgorithmIdentifier = SigUtils.MakeAlgId(AOAlgorithmID.GetOID("RSA"));

            // Firma PKCS#1 codificada
            Asn1OctetString encodedPKCS1Signature = new DerOctetString(signature);

            // Atributos firmados
            Asn1Set asn1SignedAttributes;

            asn1SignedAttributes = (Asn1Set)Asn1Object.FromByteArray(signedAttributes);

            // SignerInfo
            Asn1EncodableVector signerInfo = new Asn1EncodableVector();

            signerInfo.Add(new SignerInfo(signerIdentifier, digestAlgorithmOID, asn1SignedAttributes, keyAlgorithmIdentifier, encodedPKCS1Signature, null));

            // ContentInfo
            ContentInfo contentInfo;

            if (content != null)
            {
                MemoryStream   baos = new MemoryStream();
                CmsProcessable msg  = new CmsProcessableByteArray(content);
                msg.Write(baos);

                contentInfo = new ContentInfo(new DerObjectIdentifier(Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.Data.Id), new BerOctetString(baos.ToArray()));
            }
            else
            {
                contentInfo = new ContentInfo(new DerObjectIdentifier(Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.Data.Id), null);
            }

            // Certificados
            List <Asn1Encodable> ce = new List <Asn1Encodable>();

            foreach (X509Certificate2 cert in signerCertificateChain)
            {
                /**
                 *
                 *  Revisar el uso que hacemos de X509CertificateStructure
                 *  ya que puede ser un posible punto de errores
                 *
                 */
                ce.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetRawCertData())));
            }
            Asn1Set certificates = SigUtils.CreateBerSetFromList(ce);

            // Algoritmos de huella digital
            Asn1EncodableVector digestAlgorithms = new Asn1EncodableVector();

            digestAlgorithms.Add(digestAlgorithmOID);

            return(new ContentInfo(
                       Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.SignedData,
                       new SignedData(
                           new DerSet(digestAlgorithms),
                           contentInfo,
                           certificates,
                           null,
                           new DerSet(signerInfo)
                           )
                       ).GetEncoded("DER"));
        }