CMS 版本 2.2 SHA256WithRSAEncryption
CMS version 2.2 SHA256WithRSAEncryption
我需要根据这些要求签署一份 json 文档:CMS 2.2 版,使用 SHA256WithRSAEncryption 算法。我正在尝试这段代码,但我没有发现 属性 是 cms 2.2 版。
有效的代码是在 Java 中编写的,此代码由 api 提供商开发。他们在C#中没有例子。
import java.security.KeyStore;
import java.security.PrivateKey;
import java.util.Base64;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import br.gov.frameworkdemoiselle.certificate.signer.factory.PKCS7Factory;
import br.gov.frameworkdemoiselle.certificate.signer.pkcs7.PKCS7Signer;
import br.gov.frameworkdemoiselle.certificate.signer.pkcs7.bc.policies.ADRBCMS_2_2;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@Path("/")
@Api(value = "assinador")
public class AssinadorLojaFranca {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Insira um JSON no formato da API Loja Franca e gere seu Base64 assinado para consumo da API.", response = String.class)
public Response assina(@QueryParam("cnpjLoja") String cnpjLoja, String payload) {
try {
if (cnpjLoja == null || cnpjLoja.trim().isEmpty()) {
return Response.status(422).entity("Favor informar o cnpjLoja por query param na URL.").build();
}
byte[] fileToSign = payload.getBytes();
// quando certificado em arquivo, precisa informar a senha
char[] senha = CertificateUtils.getSenhaCertificado(cnpjLoja);
// Para certificado em arquivo A1
KeyStore ks = CertificateUtils.getKeyStoreFile(cnpjLoja);
if (ks == null) {
return Response.status(422)
.entity("Não foi possível encontrar o certificado para o cnpjLoja informado.").build();
}
String alias = CertificateUtils.getAlias(ks);
/* Parametrizando o objeto doSign */
PKCS7Signer signer = PKCS7Factory.getInstance().factoryDefault();
signer.setCertificates(ks.getCertificateChain(alias));
signer.setPrivateKey((PrivateKey) ks.getKey(alias, senha));
signer.setSignaturePolicy(new ADRBCMS_2_2());
// Assinatura atachada
signer.setAttached(true);
byte[] signature = signer.signer(fileToSign);
/* Valida o conteudo antes de gravar em arquivo */
if (signature != null) {
Boolean valid = signer.check(fileToSign, signature);
if (valid) {
System.out.println("A assinatura foi validada.");
} else {
System.out.println("A assinatura foi invalidada!");
}
return Response.ok().entity(Base64.getEncoder().encode(signature))
.header("Content-Type", "application/text; charset=utf-8").build();
}
return Response.serverError().build();
} catch (Exception ex) {
ex.printStackTrace();
return Response.serverError().build();
}
}
}
需要用C#实现。我没有找到 属性 在 class CmsSigner.
中设置 c# signer.setSignaturePolicy(new ADRBCMS_2_2())
private string AssinaJSON(string rJSON)
{
string wRetorno = "";
try
{
byte[] data = Encoding.UTF8.GetBytes(rJSON);
SignedCms signedCms = new SignedCms(new ContentInfo(data), true);
CmsSigner Signer = new CmsSigner(PUCert);
Signer.DigestAlgorithm = new Oid("1.2.840.113549.1.1.11");
signedCms.ComputeSignature(Signer);
byte[] wResult = signedCms.Encode();
wRetorno = Convert.ToBase64String(wResult);
}
catch (Exception ex) { }
return wRetorno;
}
有趣,
无论如何我都试过了,但它从来没有达到由可用订阅者计费的那个。我还没有找到如何在 C# 中通过 SignedCms / CmsSigner 设置 CMS 策略版本 2.2。如何使用 DEMOISELLE 组件 (https://www.frameworkdemoiselle.gov.br/),仅在 Java 中可用。我已经联系了一个SERPRO,但我还没有回来。
我在这家公司工作。遵循使用 BouncyCastle + DOC-ICP 策略版本 2.2 在 C# 中实现的功能示例:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using Org.BouncyCastle.Cms;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Store;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.Esf;
namespace assinador
{
class Program
{
static void Main(string[] args)
{
byte[] entradaArray = File.ReadAllBytes(@"certificado/arquivoTeste.txt");
AsymmetricKeyParameter chavePrivada;
X509Certificate certificadoX509 = getCertificadoX509(@"certificado/certificado.p12", "123!@#", out chavePrivada);
SHA512Managed hashSHA512 = new SHA512Managed();
SHA256Managed hashSHA256 = new SHA256Managed();
byte[] certificadoX509Hash = hashSHA256.ComputeHash(certificadoX509.GetEncoded());
byte[] EntradaHash = hashSHA512.ComputeHash(entradaArray);
CmsSignedDataGenerator geradorCms = new CmsSignedDataGenerator();
//
//atributos
//
Asn1EncodableVector atributosAssinados = new Asn1EncodableVector();
//1.2.840.113549.1.9.3 -> ContentType
//1.2.840.113549.1.7.1 -> RSA Security Data Inc
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet(new DerObjectIdentifier("1.2.840.113549.1.7.1"))));
//1.2.840.113549.1.9.5 -> Signing Time
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.SigningTime, new DerSet(new DerUtcTime(DateTime.Now))));
//1.2.840.113549.1.9.4 -> messageDigest
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(EntradaHash))));
//2.16.840.1.101.3.4.2.3 -> SHA-512
//2.16.840.1.101.3.4.2.1 -> SHA-256
//1.2.840.113549.1.9.16.5.1 -> sigPolicyQualifier-spuri
DerObjectIdentifier identificadorPolicyID = new DerObjectIdentifier("1.2.840.113549.1.9.16.2.15");
byte[] policyHASH = System.Text.Encoding.ASCII.GetBytes("0F6FA2C6281981716C95C79899039844523B1C61C2C962289CDAC7811FEEE29E");
List<SigPolicyQualifierInfo> sigPolicyQualifierInfos = new List<SigPolicyQualifierInfo>();
Org.BouncyCastle.Asn1.X509.AlgorithmIdentifier algoritmoIdentificador = new Org.BouncyCastle.Asn1.X509.AlgorithmIdentifier("2.16.840.1.101.3.4.2.3");
SigPolicyQualifierInfo bcSigPolicyQualifierInfo = new SigPolicyQualifierInfo(new DerObjectIdentifier("1.2.840.113549.1.9.16.5.1"), new DerIA5String("http://politicas.icpbrasil.gov.br/PA_AD_RB_v2_2.der"));
sigPolicyQualifierInfos.Add(bcSigPolicyQualifierInfo);
SignaturePolicyId signaturePolicyId = new SignaturePolicyId(DerObjectIdentifier.GetInstance(new DerObjectIdentifier("2.16.76.1.7.1.6.2.2")), new OtherHashAlgAndValue(algoritmoIdentificador, new DerOctetString(policyHASH)), sigPolicyQualifierInfos);
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(identificadorPolicyID, new DerSet(signaturePolicyId)));
//1.2.840.113549.1.9.16.2.47 -> id-aa-signingCertificateV2
Org.BouncyCastle.Asn1.Ess.EssCertIDv2 essCertIDv2;
essCertIDv2 = new Org.BouncyCastle.Asn1.Ess.EssCertIDv2(certificadoX509Hash);
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(new DerObjectIdentifier("1.2.840.113549.1.9.16.2.47"), new DerSet(essCertIDv2)));
AttributeTable atributosAssinadosTabela = new AttributeTable(atributosAssinados);
//geradorCms.AddSigner(chavePrivada, certificadoX509, CmsSignedDataGenerator.DigestSha256, new DefaultSignedAttributeTableGenerator(atributosAssinadosTabela), null);
geradorCms.AddSigner(chavePrivada, certificadoX509, CmsSignedDataGenerator.DigestSha512, new DefaultSignedAttributeTableGenerator(atributosAssinadosTabela), null);
List<X509Certificate> certificadoX509Lista = new List<X509Certificate>();
certificadoX509Lista.Add(certificadoX509);
//storeCerts.AddRange(chain);
X509CollectionStoreParameters parametrosArmazem = new X509CollectionStoreParameters(certificadoX509Lista);
IX509Store armazemCertificado = X509StoreFactory.Create("CERTIFICATE/COLLECTION", parametrosArmazem);
geradorCms.AddCertificates(armazemCertificado);
var dadosAssinado = geradorCms.Generate(new CmsProcessableByteArray(entradaArray), true); // encapsulate = false for detached signature
Console.WriteLine("Codificado => " + Convert.ToBase64String(dadosAssinado.GetEncoded()));
}
public static X509Certificate getCertificadoX509(string arquivoCertificado, string senha, out AsymmetricKeyParameter chavePrivada)
{
chavePrivada = null;
using (FileStream certificadoStream = new FileStream(arquivoCertificado, FileMode.Open, FileAccess.Read))
{
Pkcs12Store armazemPkcs12 = new Pkcs12Store();
armazemPkcs12.Load(certificadoStream, senha.ToCharArray());
string certificadoCN = armazemPkcs12.Aliases.Cast<string>().FirstOrDefault(n => armazemPkcs12.IsKeyEntry(n));
//Console.WriteLine("keyAlias => " + certificadoCN);
chavePrivada = armazemPkcs12.GetKey(certificadoCN).Key;
return (X509Certificate)armazemPkcs12.GetCertificate(certificadoCN).Certificate;
}
}
}
}
我需要根据这些要求签署一份 json 文档:CMS 2.2 版,使用 SHA256WithRSAEncryption 算法。我正在尝试这段代码,但我没有发现 属性 是 cms 2.2 版。
有效的代码是在 Java 中编写的,此代码由 api 提供商开发。他们在C#中没有例子。
import java.security.KeyStore;
import java.security.PrivateKey;
import java.util.Base64;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import br.gov.frameworkdemoiselle.certificate.signer.factory.PKCS7Factory;
import br.gov.frameworkdemoiselle.certificate.signer.pkcs7.PKCS7Signer;
import br.gov.frameworkdemoiselle.certificate.signer.pkcs7.bc.policies.ADRBCMS_2_2;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@Path("/")
@Api(value = "assinador")
public class AssinadorLojaFranca {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Insira um JSON no formato da API Loja Franca e gere seu Base64 assinado para consumo da API.", response = String.class)
public Response assina(@QueryParam("cnpjLoja") String cnpjLoja, String payload) {
try {
if (cnpjLoja == null || cnpjLoja.trim().isEmpty()) {
return Response.status(422).entity("Favor informar o cnpjLoja por query param na URL.").build();
}
byte[] fileToSign = payload.getBytes();
// quando certificado em arquivo, precisa informar a senha
char[] senha = CertificateUtils.getSenhaCertificado(cnpjLoja);
// Para certificado em arquivo A1
KeyStore ks = CertificateUtils.getKeyStoreFile(cnpjLoja);
if (ks == null) {
return Response.status(422)
.entity("Não foi possível encontrar o certificado para o cnpjLoja informado.").build();
}
String alias = CertificateUtils.getAlias(ks);
/* Parametrizando o objeto doSign */
PKCS7Signer signer = PKCS7Factory.getInstance().factoryDefault();
signer.setCertificates(ks.getCertificateChain(alias));
signer.setPrivateKey((PrivateKey) ks.getKey(alias, senha));
signer.setSignaturePolicy(new ADRBCMS_2_2());
// Assinatura atachada
signer.setAttached(true);
byte[] signature = signer.signer(fileToSign);
/* Valida o conteudo antes de gravar em arquivo */
if (signature != null) {
Boolean valid = signer.check(fileToSign, signature);
if (valid) {
System.out.println("A assinatura foi validada.");
} else {
System.out.println("A assinatura foi invalidada!");
}
return Response.ok().entity(Base64.getEncoder().encode(signature))
.header("Content-Type", "application/text; charset=utf-8").build();
}
return Response.serverError().build();
} catch (Exception ex) {
ex.printStackTrace();
return Response.serverError().build();
}
}
}
需要用C#实现。我没有找到 属性 在 class CmsSigner.
中设置 c# signer.setSignaturePolicy(new ADRBCMS_2_2())private string AssinaJSON(string rJSON)
{
string wRetorno = "";
try
{
byte[] data = Encoding.UTF8.GetBytes(rJSON);
SignedCms signedCms = new SignedCms(new ContentInfo(data), true);
CmsSigner Signer = new CmsSigner(PUCert);
Signer.DigestAlgorithm = new Oid("1.2.840.113549.1.1.11");
signedCms.ComputeSignature(Signer);
byte[] wResult = signedCms.Encode();
wRetorno = Convert.ToBase64String(wResult);
}
catch (Exception ex) { }
return wRetorno;
}
有趣,
无论如何我都试过了,但它从来没有达到由可用订阅者计费的那个。我还没有找到如何在 C# 中通过 SignedCms / CmsSigner 设置 CMS 策略版本 2.2。如何使用 DEMOISELLE 组件 (https://www.frameworkdemoiselle.gov.br/),仅在 Java 中可用。我已经联系了一个SERPRO,但我还没有回来。
我在这家公司工作。遵循使用 BouncyCastle + DOC-ICP 策略版本 2.2 在 C# 中实现的功能示例:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using Org.BouncyCastle.Cms;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Store;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.Esf;
namespace assinador
{
class Program
{
static void Main(string[] args)
{
byte[] entradaArray = File.ReadAllBytes(@"certificado/arquivoTeste.txt");
AsymmetricKeyParameter chavePrivada;
X509Certificate certificadoX509 = getCertificadoX509(@"certificado/certificado.p12", "123!@#", out chavePrivada);
SHA512Managed hashSHA512 = new SHA512Managed();
SHA256Managed hashSHA256 = new SHA256Managed();
byte[] certificadoX509Hash = hashSHA256.ComputeHash(certificadoX509.GetEncoded());
byte[] EntradaHash = hashSHA512.ComputeHash(entradaArray);
CmsSignedDataGenerator geradorCms = new CmsSignedDataGenerator();
//
//atributos
//
Asn1EncodableVector atributosAssinados = new Asn1EncodableVector();
//1.2.840.113549.1.9.3 -> ContentType
//1.2.840.113549.1.7.1 -> RSA Security Data Inc
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet(new DerObjectIdentifier("1.2.840.113549.1.7.1"))));
//1.2.840.113549.1.9.5 -> Signing Time
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.SigningTime, new DerSet(new DerUtcTime(DateTime.Now))));
//1.2.840.113549.1.9.4 -> messageDigest
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(EntradaHash))));
//2.16.840.1.101.3.4.2.3 -> SHA-512
//2.16.840.1.101.3.4.2.1 -> SHA-256
//1.2.840.113549.1.9.16.5.1 -> sigPolicyQualifier-spuri
DerObjectIdentifier identificadorPolicyID = new DerObjectIdentifier("1.2.840.113549.1.9.16.2.15");
byte[] policyHASH = System.Text.Encoding.ASCII.GetBytes("0F6FA2C6281981716C95C79899039844523B1C61C2C962289CDAC7811FEEE29E");
List<SigPolicyQualifierInfo> sigPolicyQualifierInfos = new List<SigPolicyQualifierInfo>();
Org.BouncyCastle.Asn1.X509.AlgorithmIdentifier algoritmoIdentificador = new Org.BouncyCastle.Asn1.X509.AlgorithmIdentifier("2.16.840.1.101.3.4.2.3");
SigPolicyQualifierInfo bcSigPolicyQualifierInfo = new SigPolicyQualifierInfo(new DerObjectIdentifier("1.2.840.113549.1.9.16.5.1"), new DerIA5String("http://politicas.icpbrasil.gov.br/PA_AD_RB_v2_2.der"));
sigPolicyQualifierInfos.Add(bcSigPolicyQualifierInfo);
SignaturePolicyId signaturePolicyId = new SignaturePolicyId(DerObjectIdentifier.GetInstance(new DerObjectIdentifier("2.16.76.1.7.1.6.2.2")), new OtherHashAlgAndValue(algoritmoIdentificador, new DerOctetString(policyHASH)), sigPolicyQualifierInfos);
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(identificadorPolicyID, new DerSet(signaturePolicyId)));
//1.2.840.113549.1.9.16.2.47 -> id-aa-signingCertificateV2
Org.BouncyCastle.Asn1.Ess.EssCertIDv2 essCertIDv2;
essCertIDv2 = new Org.BouncyCastle.Asn1.Ess.EssCertIDv2(certificadoX509Hash);
atributosAssinados.Add(new Org.BouncyCastle.Asn1.Cms.Attribute(new DerObjectIdentifier("1.2.840.113549.1.9.16.2.47"), new DerSet(essCertIDv2)));
AttributeTable atributosAssinadosTabela = new AttributeTable(atributosAssinados);
//geradorCms.AddSigner(chavePrivada, certificadoX509, CmsSignedDataGenerator.DigestSha256, new DefaultSignedAttributeTableGenerator(atributosAssinadosTabela), null);
geradorCms.AddSigner(chavePrivada, certificadoX509, CmsSignedDataGenerator.DigestSha512, new DefaultSignedAttributeTableGenerator(atributosAssinadosTabela), null);
List<X509Certificate> certificadoX509Lista = new List<X509Certificate>();
certificadoX509Lista.Add(certificadoX509);
//storeCerts.AddRange(chain);
X509CollectionStoreParameters parametrosArmazem = new X509CollectionStoreParameters(certificadoX509Lista);
IX509Store armazemCertificado = X509StoreFactory.Create("CERTIFICATE/COLLECTION", parametrosArmazem);
geradorCms.AddCertificates(armazemCertificado);
var dadosAssinado = geradorCms.Generate(new CmsProcessableByteArray(entradaArray), true); // encapsulate = false for detached signature
Console.WriteLine("Codificado => " + Convert.ToBase64String(dadosAssinado.GetEncoded()));
}
public static X509Certificate getCertificadoX509(string arquivoCertificado, string senha, out AsymmetricKeyParameter chavePrivada)
{
chavePrivada = null;
using (FileStream certificadoStream = new FileStream(arquivoCertificado, FileMode.Open, FileAccess.Read))
{
Pkcs12Store armazemPkcs12 = new Pkcs12Store();
armazemPkcs12.Load(certificadoStream, senha.ToCharArray());
string certificadoCN = armazemPkcs12.Aliases.Cast<string>().FirstOrDefault(n => armazemPkcs12.IsKeyEntry(n));
//Console.WriteLine("keyAlias => " + certificadoCN);
chavePrivada = armazemPkcs12.GetKey(certificadoCN).Key;
return (X509Certificate)armazemPkcs12.GetCertificate(certificadoCN).Certificate;
}
}
}
}