Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ASN1.parse() error #7

Closed
pedroserretti opened this issue Mar 4, 2024 · 4 comments
Closed

ASN1.parse() error #7

pedroserretti opened this issue Mar 4, 2024 · 4 comments
Labels
question Further information is requested

Comments

@pedroserretti
Copy link

I'm doing a function that i'm signing a XML.
Before i was testing with the same certificate, and it does successfully.

Now, i'm doing some tests, but unfortunally, when i test with another certificate, it occurs a new error, in ASN1.parse function.
Can anyone help me with this??

static Future<(bool, String)> assinarDocumento(String sCertificadoConteudo, String sSenhaCertificado, String sTagAssinar, String arquivoXml, String sXmlString) async {
    bool responseOk = true;
    String sCert = "";
    String sMensagem = "";
    Uint8List chaveBytes;
    // Uint8List certBytes;

    XmlDocument document = XmlDocument.parse(sXmlString);
    document.normalize(trimAllWhitespace: true);
    Iterable<XmlElement> tagElements = document.findAllElements(sTagAssinar);

    switch (tagElements.length) {
      case 0:
        sMensagem = "A tag a ser assinada não existe.";
        return (!responseOk, sMensagem);
      case 1:
        try {
          (chaveBytes, sCert) = await FNfeNfceGerais.extrairChavePrivadaCertificado(sCertificadoConteudo, sSenhaCertificado);

          SignedXml sig = SignedXml()
            ..signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
            ..canonicalizationAlgorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
            ..addReference(
              "//*[local-name()='$sTagAssinar']",
              ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"],
            )
            ..signingKey = chaveBytes;
          sig.computeSignature(document.toXmlString());

          XmlDocument newDocument = XmlDocument.parse(sig.signedXml);

          XmlElement keyInfo = XmlElement(XmlName('KeyInfo'), [], [
            XmlElement(XmlName('X509Data'), [], [
              XmlElement(XmlName('X509Certificate'), [], [XmlText(sCert.replaceAll("-----BEGIN CERTIFICATE-----", "").replaceAll("-----END CERTIFICATE-----", "").replaceAll(RegExp(r'\s+'), "").trim())]),
            ]),
          ]);

          XmlElement signatureNode = newDocument.findAllElements("Signature").first;
          signatureNode.children.add(keyInfo);

          await File(arquivoXml).writeAsString(newDocument.toXmlString(pretty: true));
          return (responseOk, "O Xml foi assinado com sucesso.");
        } catch (e, stacktrace) {
          return (!responseOk, "Erro: $e\n Stack Trace: $stacktrace");
        }
      default:
        return (!responseOk, "Existe mais de uma tag a ser assinada.");
    }
  }
static Future<(Uint8List, String)> extrairChavePrivadaCertificado(String sCertificadoConteudo, String sSenhaCertificado) async {
    String sCert = "";
    Uint8List? chaveBytes;
    Uint8List certBytes = base64Decode(sCertificadoConteudo);
    List<String> results = Pkcs12Utils.parsePkcs12(certBytes, password: FGeral.descriptografarTexto(sSenhaCertificado, tlAsc: false));

    for (String conteudo in results) {
      if (conteudo.contains("PRIVATE KEY")) {
        // chaveBytes = conteudo.codeUnits;
        conteudo = conteudo.replaceAll("-----BEGIN PRIVATE KEY-----", "").replaceAll("-----END PRIVATE KEY-----", "").replaceAll("\n", "").replaceAll("\r", "");
        Uint8List x = utf8.encode("-----BEGIN PRIVATE KEY-----");
        Uint8List y = FGeral.stringToUint8List(conteudo);
        Uint8List z = utf8.encode("-----END PRIVATE KEY-----");
        chaveBytes = Uint8List.fromList(x + y + z);
      }
      if (conteudo.contains("CERTIFICATE")) {
        sCert = conteudo;
        // certBytes = utf8.encode(conteudo);
      }
    }
    return (chaveBytes ?? Uint8List(0), sCert);
  }

That's my CallStack:

#0 ASN1Object.parse (package:ninja_asn1/src/ninja_asn1_base.dart:120:9)
#1 ASN1Sequence.parse (package:ninja_asn1/src/ninja_asn1_base.dart:211:33)
#2 new ASN1Sequence.decode (package:ninja_asn1/src/ninja_asn1_base.dart:180:70)
#3 new RSAPrivateKey.fromASN1 (package:ninja/asymmetric/rsa/rsa.dart:271:32)
#4 new RSAPrivateKey.fromPEM (package:ninja/asymmetric/rsa/rsa.dart:325:26)
#5 RSASHA1.getSignature (package:xml_crypto/src/signed_xml.dart:980:31)
#6 SignedXml._calculateSignatureValue (package:xml_crypto/src/signed_xml.dart:291:16)
#7 SignedXml.computeSignature (package:xml_crypto/src/signed_xml.dart:659:7)
#8 FNfeNfceGerais.assinarDocumento (package:vip12/funcoes/nfeNfce/fNfeNfceGerais.dart:67:15)
e: UnimplementedError
message: null

That's urgent, please, someone help me, i need answers!

@scribetw
Copy link
Collaborator

scribetw commented Mar 5, 2024

It seems your RSA private key is not valid in PEM format.

I suggest checking chaveBytes first, maybe something was wrong.

import 'dart:convert';

print(utf8.decode(chaveBytes));

And it should be like the following in text form:

-----BEGIN PRIVATE KEY-----
MIICdwIBADA....(omitted)
-----END PRIVATE KEY-----

@scribetw scribetw added the question Further information is requested label Mar 5, 2024
@pedroserretti
Copy link
Author

pedroserretti commented Mar 5, 2024

It seems your RSA private key is not valid in PEM format.

I suggest checking chaveBytes first, maybe something was wrong.

import 'dart:convert';

print(utf8.decode(chaveBytes));

And it should be like the following in text form:

-----BEGIN PRIVATE KEY-----
MIICdwIBADA....(omitted)
-----END PRIVATE KEY-----

Hi, thanks for the reply!

My certificate look like this:
image
image

Can i send you my certificate with my private key and my sign code?
In private or an email?

PS:
The byte when the problem occurs is "160"
#0 ASN1Object.parse (package:ninja_asn1/src/ninja_asn1_base.dart:120:9)

Maybe this can help.

Thanks in advance.

@pedroserretti
Copy link
Author

It seems your RSA private key is not valid in PEM format.

I suggest checking chaveBytes first, maybe something was wrong.

import 'dart:convert';

print(utf8.decode(chaveBytes));

And it should be like the following in text form:

-----BEGIN PRIVATE KEY-----
MIICdwIBADA....(omitted)
-----END PRIVATE KEY-----

Another information for you.

I checked my certificate at:
https://www.sslshopper.com/certificate-key-matcher.html

image

https://www.sslshopper.com/certificate-decoder.html

image

@scribetw
Copy link
Collaborator

scribetw commented Mar 6, 2024

Hi, since the stack trace shows the error is from ninja and ninja_asn1, I suggest you go to their issue tracker to post an issue instead.

Thanks.

@scribetw scribetw closed this as not planned Won't fix, can't repro, duplicate, stale Mar 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants