11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Security . Cryptography ;
5+ using System . Security . Cryptography . X509Certificates ;
6+ using System . Text ;
47using DFe . Classes . Entidades ;
58using DFe . Classes . Flags ;
69using DFe . Utils ;
@@ -373,7 +376,7 @@ public static string ObterUrlQrCode(this infNFeSupl infNFeSupl, Classes.NFe nfe,
373376 case VersaoQrCode . QrCodeVersao2 :
374377 return ObterUrlQrCode2 ( infNFeSupl , nfe , cIdToken , csc , versaoServico ) ;
375378 case VersaoQrCode . QrCodeVersao3 :
376- return ObterUrlQrCode3 ( infNFeSupl , nfe , versaoServico ) ;
379+ throw new ArgumentOutOfRangeException ( "versaoQrCode" , versaoQrCode , "Para versão 3.0 do QR-Code utilize a função ObterUrlQrCode3" ) ;
377380 default :
378381 throw new ArgumentOutOfRangeException ( "versaoQrCode" , versaoQrCode , null ) ;
379382 }
@@ -492,7 +495,7 @@ public static string ObterUrlQrCode2ComParametro(this infNFeSupl infNFeSupl, Tip
492495 /// <summary>
493496 /// Obtém a URL para uso no QR-Code, versão 3.0 - leiaute 4.00+
494497 /// </summary>
495- private static string ObterUrlQrCode3 ( infNFeSupl infNFeSupl , Classes . NFe nfe , VersaoServico versaoServico )
498+ public static string ObterUrlQrCode3 ( infNFeSupl infNFeSupl , Classes . NFe nfe , VersaoServico versaoServico , X509Certificate2 certificadoDigital , Encoding encoding = null )
496499 {
497500 const string pipe = "|" ;
498501
@@ -547,15 +550,36 @@ private static string ObterUrlQrCode3(infNFeSupl infNFeSupl, Classes.NFe nfe, Ve
547550 idDest
548551 ) ;
549552
550- // Assinatura SHA-1 dos parâmetros + CSC
551- var assinatura = Conversao . ObterHexSha1DeString ( dadosBase ) ;
553+ if ( encoding == null )
554+ encoding = Encoding . UTF8 ;
555+
556+ if ( certificadoDigital == null )
557+ throw new ArgumentNullException ( nameof ( certificadoDigital ) , "Para gerar a assinatura do QR-Code versão 3.0 EM CONTINGENCIA é necessário informar o certificado digital utilizado na assinatura da NFC-e." ) ;
558+
559+ // Assinatura SHA-1 dos parâmetros COM uso do certificado digital
560+ var assinatura = Convert . ToBase64String ( CreateSignaturePkcs1 ( certificadoDigital , encoding . GetBytes ( dadosBase ) ) ) ;
552561 dadosBase = string . Concat ( dadosBase , pipe , assinatura ) ;
553562 }
554563
564+ // Monta a URL base (ja com ?p= ao final)
555565 var url = ObterUrlQrCode2ComParametro ( infNFeSupl , nfe . infNFe . ide . tpAmb , nfe . infNFe . ide . cUF , versaoServico ) ;
556566
557- // Monta a URL base
558- return string . Concat ( url , "?p=" , dadosBase ) ;
567+ return string . Concat ( url , dadosBase ) ;
568+ }
569+
570+ private static byte [ ] CreateSignaturePkcs1 ( X509Certificate2 certificado , byte [ ] Value )
571+ {
572+ var rsa = certificado . GetRSAPrivateKey ( ) ;
573+
574+ RSAPKCS1SignatureFormatter rsaF = new RSAPKCS1SignatureFormatter ( rsa ) ;
575+
576+ SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider ( ) ;
577+
578+ byte [ ] hash = sha1 . ComputeHash ( Value ) ;
579+
580+ rsaF . SetHashAlgorithm ( "SHA1" ) ;
581+
582+ return rsaF . CreateSignature ( hash ) ;
559583 }
560584 }
561585}
0 commit comments