/// <summary> /// Genera la firma CADES /// </summary> /// <param name="data">Datos a firmar</param> /// <param name="privateKey">Clave privada usada para la firma</param> /// <param name="certificado">Certificado del firmante</param> /// <param name="algo">Algoritmo de firma</param> /// <param name="format">Formato de firma</param> /// <returns>Firma en formato binario</returns> public static byte[] getCades(byte[] data, RsaKeyParameters privateKey, byte[] certificado, string algo, string format) { GenCAdESEPESSignedData prueba = new GenCAdESEPESSignedData(); Dictionary <string, string> p1 = new Dictionary <string, string>(); p1.Add("format", format); p1.Add("mode", "implicit"); p1.Add("policyIdentifier", null); p1.Add("policyIdentifierHash", null); p1.Add("policyIdentifierHashAlgorithm", null); p1.Add("policyQualifier", null); p1.Add("signingCertificateV2", "false"); AdESPolicy politica = new AdESPolicy(p1); X509Certificate2 cert = new X509Certificate2(); cert.SetRawCertData(certificado); cert.SetKey(privateKey); X509Certificate2[] certs = new X509Certificate2[1]; certs[0] = cert; AOCAdESSigner cadesSigner = new AOCAdESSigner(); byte[] datos = cadesSigner.sign(data, algo, certs, p1); return(datos); }
private static PolicyInformation[] GetPolicyInformation(AdESPolicy policy) { if (policy == null) { throw new ArgumentException("La politica de firma no puede ser nula en este punto"); } /** * PolicyQualifierInfo ::= SEQUENCE { * policyQualifierId PolicyQualifierId, * qualifier ANY DEFINED BY policyQualifierId } */ PolicyQualifierID pqid = PolicyQualifierID.IdQtCps; DerIA5String uri = null; if (policy.GetPolicyQualifier() != null && !policy.GetPolicyQualifier().Equals("")) { uri = new DerIA5String(policy.GetPolicyQualifier().ToString()); } Asn1EncodableVector v = new Asn1EncodableVector(); PolicyQualifierInfo pqi = null; if (uri != null) { v.Add(pqid); v.Add(uri); /** * * ESTO TIENE ALTAS PROBABILIDADES DE FALLAR * */ pqi = PolicyQualifierInfo.GetInstance(new DerSequence(v)); } /** * PolicyInformation ::= SEQUENCE { * policyIdentifier CertPolicyId, * policyQualifiers SEQUENCE SIZE (1..MAX) OF * PolicyQualifierInfo OPTIONAL } */ if (policy.GetPolicyQualifier() == null || pqi == null) { return(new PolicyInformation[] { new PolicyInformation(new DerObjectIdentifier(policy.GetPolicyIdentifier().ToLower().Replace("urn:oid:", ""))) }); } return(new PolicyInformation[] { new PolicyInformation(new DerObjectIdentifier(policy.GetPolicyIdentifier().ToLower().Replace("urn:oid:", "")), new DerSequence(pqi)) }); }
public static byte[] PreSign(String digestAlgorithmName, byte[] content, X509Certificate2[] signerCertificateChain, AdESPolicy policy, bool signingCertificateV2, byte[] messageDigest, DateTime signDate, bool padesMode, String contentType, String contentDescription) { if (signerCertificateChain == null || signerCertificateChain.Length == 0) { throw new ArgumentException("La cadena de certificados debe contener al menos una entrada"); } // Atributos firmados Asn1Set signedAttributes; signedAttributes = SigUtils.GetAttributeSet( new Org.BouncyCastle.Asn1.Cms.AttributeTable( CAdESUtils.GenerateSignerInfo( signerCertificateChain[0], digestAlgorithmName, content, policy, signingCertificateV2, messageDigest, signDate, padesMode, contentType, contentDescription ) ) ); return(signedAttributes.GetEncoded("DER")); }
public static byte[] generateSignedData( P7ContentSignerParameters parameters, bool omitContent, AdESPolicy policy, bool signingCertificateV2, X509Certificate2 keyEntry, byte[] messageDigest, bool padesMode, String contentType, String contentDescription) { if (parameters == null) { throw new ArgumentNullException("Los parametros no pueden ser nulos"); } String signatureAlgorithm = parameters.GetSignatureAlgorithm(); X509Certificate2[] signerCertificateChain = parameters.GetSignerCertificateChain(); DateTime signDate = DateTime.Now; // Ya que el contenido de la firma puede ser grande, lo obtenemos solo al principio byte[] content = parameters.GetContent(); byte[] preSignature = CAdESTriPhaseSigner.PreSign( AOSignConstants.GetDigestAlgorithmName(signatureAlgorithm), (omitContent) ? null : content, signerCertificateChain, policy, signingCertificateV2, (messageDigest == null && content != null) ? Digester.Digest(content, AOSignConstants.GetDigestAlgorithmName(signatureAlgorithm)) : messageDigest, signDate, padesMode, contentType, contentDescription ); byte[] signature = new AOPkcs1Signer().sign(preSignature, signatureAlgorithm, keyEntry); return(CAdESTriPhaseSigner.PostSign( AOSignConstants.GetDigestAlgorithmName(signatureAlgorithm), (omitContent) ? null : content, signerCertificateChain, signature, // Volvemos a crear la prefirma simulando una firma trifasica en la que la postfirma no cuenta con el // resultado de la prefirma CAdESTriPhaseSigner.PreSign( AOSignConstants.GetDigestAlgorithmName(signatureAlgorithm), (omitContent) ? null : content, signerCertificateChain, policy, signingCertificateV2, (messageDigest == null && content != null) ? Digester.Digest(content, AOSignConstants.GetDigestAlgorithmName(signatureAlgorithm)) : messageDigest, signDate, padesMode, contentType, contentDescription ) )); }
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); }