Xml validation failed with RSA256with rsa Algorithm - c#

I am trying to validate offline aadhar ekyc XML file with the sample code. But the validation keeps failing, I am not sure if it's the code error or error in the .cer file.
I am using SHA256withRSA algorithm to validate the XML file as mention in the documentation and sample code.
Same thing happening with Python Code.
Is there any special encoding feed into the validation function?
using System;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
namespace test
{
class MainClass
{
public static void Main(string[] args)
{
// link ->
//https://drive.google.com/file/d/1aSv3HJUFf5_42Z-FqpdVHEk5b3VA3T3D/view
string XMLFilePath = "offlineaadhaar.xml"; //Get the XML file
// link ->
//https://drive.google.com/file/d/1FW4ciIhZqJuelOcGF2x6VaBCSDO9J-gM/view
string KeyFilePath = "okyc-publickey.cer"; //Get the public key certificate file
XmlDocument ObjXmlDocument = new XmlDocument();
ObjXmlDocument.Load(XMLFilePath); //Load the XML
XmlAttributeCollection SignatureElement = ObjXmlDocument.DocumentElement.Attributes; //Get the all XML attribute
string SignatureValue = SignatureElement.GetNamedItem("s").InnerXml; // Get Signature value
SignatureElement.RemoveNamedItem("s");//Remove the signature "s" attribute from XML and get the new XML to validate
//Console.WriteLine(SignatureElement);
/*----------------Read and parse the public key as string-----------------------*/
X509Certificate2 ObjX509Certificate2 = new X509Certificate2(KeyFilePath, "public"); //Initialize the public ket certificate file
Org.BouncyCastle.X509.X509Certificate objX509Certificate;
Org.BouncyCastle.X509.X509CertificateParser objX509CertificateParser = new Org.BouncyCastle.X509.X509CertificateParser();
objX509Certificate = objX509CertificateParser.ReadCertificate(ObjX509Certificate2.GetRawCertData());
/*----------------End-----------------------*/
//Console.WriteLine(objX509Certificate);
/* Init alg */
Org.BouncyCastle.Crypto.ISigner signer = Org.BouncyCastle.Security.SignerUtilities.GetSigner("SHA256withRSA");
//Console.WriteLine(signer);
/* Populate key */
signer.Init(false, objX509Certificate.GetPublicKey());
/* Get the signature into bytes */
var expectedSig = Convert.FromBase64String(SignatureValue);
/* Get the bytes to be signed from the string */
var msgBytes = System.Text.Encoding.UTF8.GetBytes(ObjXmlDocument.InnerXml);
/* Calculate the signature and see if it matches */
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
Console.WriteLine(msgBytes.Length);
bool Flag = signer.VerifySignature(expectedSig);
if (Flag)
{
Console.WriteLine("XML Validate Successfully");
}
else
{
Console.WriteLine("XML Validation Failed");
}
}
}
}

Related

Howto create the pdf hash ahead of time using iText IExternalSignatureContainer

I'm using iText 7 for applying signatures to pdf documents. I also use my own implementation of IExternalSignatureContainer in order to integrate the certificates into the PKCS7 CMS since the signing service only returns a PKCS1 signature.
The signature process is asynchrony (user has to authenticate) i'd like to do the following:
Prepare the document (PdfReader)
Get the hash value of the document back to the user
Throw the document away (PdfReader)
Let the user authenticate (Not directly related with the iText signing process) and create the signature (PKCS1)
If the user is authenticated, Prepare the document again and apply the signature.
Reason for this is that i don't have too keep the prepared document in memory and also for batch signing.
My problem is that the hash value created is always different. (Even if i set the date/time via pdfSigner.SetSignDate to the same value) or every PdfReader/PdfSigner instance.
//Create the hash of of the pdf document
//Part of my IExternalSignatureContainer Sign method
//Called from iText pdfSigner.SignExternalContainer
//The produced hash is always different
byte[] hash = DigestAlgorithms.Digest(pdfStream, DigestAlgorithms.GetMessageDigest(hashAlgorithm));
Question: Is there a way to
Produce the hash of a pdf document "ahead of time" on one instance of the PdfReader
Create the signature
Apply the signature on a different instance of the PdfReader
Attached is a complete example of the process (Including the signature creation which actually needs to be done by a different service)
using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using iText.Kernel.Pdf;
using iText.Signatures;
using Org.BouncyCastle.X509;
using X509Certificate = Org.BouncyCastle.X509.X509Certificate;
namespace SignExternalTestManuel
{
class Program
{
const string filePath = #"c:\temp\pdfsign\";
public static string pdfToSign = Path.Combine(filePath, #"test.pdf");
public static string destinationFile = Path.Combine(filePath, "test_signed.pdf");
public static string LocalUserCertificatePublicKey = Path.Combine(filePath, "BITSignTestManuel5Base64.cer");
public static string LocalCaCertificatePublicKey = Path.Combine(filePath, "BITRoot5Base64.cer");
public static string privateKeyFile = Path.Combine(filePath, "BITSignTestManuel5.pfx");
public static string privateKeyPassword = "test";
public static void Main(String[] args)
{
PdfReader reader = new PdfReader(pdfToSign);
using (FileStream os = new FileStream(destinationFile, FileMode.OpenOrCreate))
{
StampingProperties stampingProperties = new StampingProperties();
stampingProperties.UseAppendMode();
PdfSigner pdfSigner = new PdfSigner(reader, os, stampingProperties);
pdfSigner.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
IExternalSignatureContainer external = new GsSignatureContainer(
PdfName.Adobe_PPKLite,
PdfName.Adbe_pkcs7_detached);
pdfSigner.SetSignDate(new DateTime(2021, 2, 22, 10, 0, 0));
pdfSigner.SetFieldName("MySignatureField");
pdfSigner.SignExternalContainer(external, 32000);
}
}
}
public class GsSignatureContainer : IExternalSignatureContainer
{
private PdfDictionary sigDic;
public GsSignatureContainer(PdfName filter, PdfName subFilter)
{
sigDic = new PdfDictionary();
sigDic.Put(PdfName.Filter, filter);
sigDic.Put(PdfName.SubFilter, subFilter);
}
/// <summary>
/// Implementation based on https://kb.itextpdf.com/home/it7kb/examples/how-to-use-a-digital-signing-service-dss-such-as-globalsign-with-itext-7#HowtouseaDigitalSigningService(DSS)suchasGlobalSign,withiText7-Examplecode
/// </summary>
/// <param name="pdfStream"></param>
/// <returns></returns>
public byte[] Sign(Stream pdfStream)
{
//Create the certificate chaing since the signature is just a PKCS1, the certificates must be added to the signature
X509Certificate[] chain = null;
string cert = System.IO.File.ReadAllText(Program.LocalUserCertificatePublicKey);
string ca = System.IO.File.ReadAllText(Program.LocalCaCertificatePublicKey);
chain = CreateChain(cert, ca);
X509CrlParser p = new X509CrlParser();
String hashAlgorithm = DigestAlgorithms.SHA256;
PdfPKCS7 pkcs7Signature = new PdfPKCS7(null, chain, hashAlgorithm, false);
//Create the hash of of the pdf document
//Part of my IExternalSignatureContainer Sign method
//Called from iText pdfSigner.SignExternalContainer
//The produced hash is always different
byte[] hash = DigestAlgorithms.Digest(pdfStream, DigestAlgorithms.GetMessageDigest(hashAlgorithm));
byte[] signature = null;
//Create the hash based on the document hash which is suitable for pdf siging with SHA256 and a X509Certificate
byte[] sh = pkcs7Signature.GetAuthenticatedAttributeBytes(hash, null, null, PdfSigner.CryptoStandard.CMS);
//Create the signature via own certificate
signature = CreateSignature(sh, Program.privateKeyFile, Program.privateKeyPassword);
pkcs7Signature.SetExternalDigest(signature, null, "RSA");
return pkcs7Signature.GetEncodedPKCS7(hash, null, null, null, PdfSigner.CryptoStandard.CMS);
}
public void ModifySigningDictionary(PdfDictionary signDic)
{
signDic.PutAll(sigDic);
}
private static X509Certificate[] CreateChain(String cert, String ca)
{
//Note: The root certificate could be omitted and it would still work
X509Certificate[] chainy = new X509Certificate[2];
X509CertificateParser parser = new X509CertificateParser();
chainy[0] = new X509Certificate(parser.ReadCertificate(Encoding.UTF8.GetBytes(cert))
.CertificateStructure);
chainy[1] = new X509Certificate(parser.ReadCertificate(Encoding.UTF8.GetBytes(ca))
.CertificateStructure);
return chainy;
}
#region "Create signature, will be done by an actual service"
private byte[] CreateSignature(byte[] hash, string privateKeyFile, string privateKeyPassword)
{
//Sign data directly with a X509Certificate
X509Certificate2 rootCertificateWithPrivateKey = new X509Certificate2();
byte[] rawData = System.IO.File.ReadAllBytes(privateKeyFile);
rootCertificateWithPrivateKey.Import(rawData, privateKeyPassword, X509KeyStorageFlags.Exportable);
using (var key = rootCertificateWithPrivateKey.GetRSAPrivateKey())
{
return key.SignData(hash, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
}
#endregion
}
}
Question: Is there a way to
Produce the hash of a pdf document "ahead of time" on one instance of the PdfReader
Create the signature
Apply the signature on a different instance of the PdfReader
This use case currently is not supported by iText, in each pass in particular
a different PDF ID is generated,
a different modification time is used, and
in case of AES encrypted PDFs the random numbers used for encryption are different.
It is possible to patch iText to use the same values in each pass, but before patching a library you should consider whether you can adapt your architecture to make a patch unnecessary.
In your case, for example, if you cannot keep the original PdfSigner instance, an alternative approach could be to have the original PdfSigner after hashing store its result file with dummy signature bytes (e.g. new byte[0]). Then, after retrieving the signature container, you can inject it into the stored file in a different service using PdfSigner.signDeferred as long as both service can access shared storage (or the first service can at least forward the file the the storage of the second service).

How to create Digital Signature with CAdES format using Pkcs11Interop in C# without data or document to sign

I am new in cryptographic programming.
I want to create only digital signature in C# with CAdES format using Pkcs11Interop library without having data or document or message to sign, I want the signature string only to use it on any json or xml file generated from my application.
I used Pkcs11Interop library because I have a smart token "Cryptoki" with unmanaged PKCS#11 dll library which I have to use to make the signature.
Here is my sample code based on Pkcs11Interop open source samples.
using System;
using System.Collections.Generic;
using Net.Pkcs11Interop.Common;
using Net.Pkcs11Interop.HighLevelAPI;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Pkcs11InteropFactories factories = new Pkcs11InteropFactories();
using (IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, #"C:\eps2003csp11.dll", AppType.MultiThreaded))
{
ILibraryInfo libraryInfo = pkcs11Library.GetInfo();
foreach (ISlot slot in pkcs11Library.GetSlotList(SlotsType.WithOrWithoutTokenPresent))
{
ISlotInfo slotInfo = slot.GetSlotInfo();
if (slotInfo.SlotFlags.TokenPresent)
{
using (ISession session = slot.OpenSession(SessionType.ReadWrite))
{
session.Login(CKU.CKU_USER, #"000000");
IObjectHandle publicKey = null;
IObjectHandle privateKey = null;
GenerateKeyPair(session, out publicKey, out privateKey);
IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_CMS_SIG);
byte[] sourceData = ConvertUtils.Utf8StringToBytes(null);
byte[] signature = session.Sign(mechanism, privateKey, sourceData);
string vStringSignature = ConvertUtils.BytesToBase64String(signature);
Console.WriteLine("Signature: " + vStringSignature);
session.DestroyObject(privateKey);
session.DestroyObject(publicKey);
session.Logout();
}
}
}
}
}
static void GenerateKeyPair(ISession session, out IObjectHandle publicKeyHandle, out IObjectHandle privateKeyHandle)
{
// The CKA_ID attribute is intended as a means of distinguishing multiple key pairs held by the same subject
byte[] ckaId = session.GenerateRandom(20);
// Prepare attribute template of new public key
List<IObjectAttribute> publicKeyAttributes = new List<IObjectAttribute>();
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, false));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, "Digital Business ERP"));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ENCRYPT, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_VERIFY, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_VERIFY_RECOVER, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_WRAP, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_MODULUS_BITS, 1024));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));
// Prepare attribute template of new private key
List<IObjectAttribute> privateKeyAttributes = new List<IObjectAttribute>();
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, "Digital Business ERP"));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SENSITIVE, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_DECRYPT, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SIGN, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SIGN_RECOVER, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_UNWRAP, true));
// Specify key generation mechanism
IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN);
// Generate key pair
session.GenerateKeyPair(mechanism, publicKeyAttributes, privateKeyAttributes, out publicKeyHandle, out privateKeyHandle);
}
}
}
If I put "null" or empty double quotes in the following sourceData variable
byte[] sourceData = ConvertUtils.Utf8StringToBytes(null);
or
byte[] sourceData = ConvertUtils.Utf8StringToBytes("");
I get error in creating signature like this
byte[] signature = session.Sign(mechanism, privateKey, sourceData);
or
byte[] signature = session.Sign(mechanism, privateKey, null);
Only when I put sample data like "Hello World" the signature string is generated successfully but it containes data string which is "Hello World" in this sample.
I want to generate signature string without any data contained, Also in my code I don't know how to set signature format to CAdES.
Tarek
I'm also struggling with the same issue, trying to produce a cades-bes signature on a json document and attach it to the original json document as a property.
This is as part of Egyptian tax authority rules for submitting signed invoices using their Api.
I tried the CMS classes of. Net core, and managed to produce the signature of the document, but the Api refuses my document, and I get a response of 400 "Bad request".
If you managed in your eduvor, please add the solution here.

Openssl verification fails

I have a zip file which I'm signing using c# code with Bouncy castle. The generated signature file is identical ( I have compared output string as well as binary code) to signature file generated with openssl using following command
openssl dgst -sha256 -sign content_private_key.pem -out content.zip.sig content.zip
But when I verify signature file (generated using c# code) using openssl it shows "Verification Failure error in dgst" error. Whereas signature file generated using openssl gets verified successfully.
Command I'm using for verification is
openssl dgst -sha256 -verify content_public_key.pem -signature content.zip.sig content.zip
openssl output
What could be the issue ?
Here is the C# code I'm using to sign the data
/// <summary>
/// Method to generate signature file
/// </summary>
private void GenerateSignatureFile(string sourceFile)
{
try
{
var bytesToSign = File.ReadAllBytes(sourceFile);
var sig = Sign(bytesToSign);
var fileContent = Encoding.GetEncoding(1252).GetString(sig);
using (var sw = File.CreateText(Path.Combine(_projectLocation, _sigFileName)))
{
sw.Write(fileContent);
}
}
catch (Exception ex)
{
LoggingService.Log(ex.Message);
var errorWhileCreatingSignatureFile = Resource.ResourceManager.GetString("ErrorWhileCreatingSignatureFile");
throw new Exception(errorWhileCreatingSignatureFile, ex);
}
}
public byte[] Sign(byte[] bytes)
{
var key = ReadPrivateKey();
/* Make the key */
var keyParameter = new RsaKeyParameters(key.IsPrivate, ((RsaPrivateCrtKeyParameters)key).Modulus, ((RsaPrivateCrtKeyParameters)key).Exponent);
/* Init alg */
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");
/* Populate key */
sig.Init(true, key);
/* Calc the signature */
sig.BlockUpdate(bytes, 0, bytes.Length);
return sig.GenerateSignature();
}
private AsymmetricKeyParameter ReadPrivateKey()
{
AsymmetricCipherKeyPair keyPair;
using (var reader = new StringReader(_privateKey))
keyPair = (AsymmetricCipherKeyPair)new PemReader(reader).ReadObject();
return keyPair.Private;
}
[Solution in comments]
If files were identical then verification will work in both cases because digital signature verification is deterministic. It means that files are not equal.
A signature result of type byte[] is binary and not text. Any attempt to apply a text encoding in any language will produce unexpected results because it contains non-representable characters
You have an issue saving binary data to file here
var fileContent = Encoding.GetEncoding(1252).GetString(sig);
using (var sw = File.CreateText(Path.Combine(_projectLocation, _sigFileName)))
Change it with
File.WriteAllBytes(string path, byte[] bytes)

How clean a X509 certified file

I made a routine to sign some proprietary binary files with PKCS#7 X509 certificates. The routine is functioning like a charm:
public static byte[] SignFile(X509Certificate2Collection certs, byte[] data, bool Tipo_A3 = false)
{
try
{
ContentInfo content = new ContentInfo(data);
SignedCms signedCms = new SignedCms(content, false);
if (VerifySign(data))
{
signedCms.Decode(data);
}
foreach (X509Certificate2 cert in certs)
{
CmsSigner signer = new CmsSigner( cert);
signer.IncludeOption = X509IncludeOption.WholeChain;
signer.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
signer.SignedAttributes.Add(new Pkcs9SigningTime(System.DateTime.Now));
if (Type_A3 == true)
{
signedCms.ComputeSignature(signer, false);
}
else
{
signedCms.ComputeSignature(signer);
}
}
return signedCms.Encode();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
return null;
}
}
My problem is related to RECOVER the original info. An 1Kb file will be transformed in a ~8Kb file, since the signature in within this file.
I need to read the data without the signature/certificate within the file, I mean, I need to recover the original data before its signing - and I don't know how to do it.
I saw that the signed file has bytes BEFORE and AFTER its original contents (I made a test using a tiny TXT file with "abcd"), but I'm affraid to consider ever the same data length before and after the original data to extract it.
I know I get the original content using this function, where DATA is the signed file:
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Pkcs;
using System.IO;
using System.Windows.Forms;
public static Int VerifyContentInfo(byte[] data)
{
try
{
SignedCms signed = new SignedCms();
signed.Decode(data);
signed.CheckSignature(true);
return signed.ContentInfo.Content.Length
}
catch
{
return null;
}
}
The problem: even knowing the length of the original data within the signed file, how securely locate and extract it using a .NET function?
Thanks for any help!
signed.ContentInfo.Content (whose value you took the length of) is the original content.

Is it possible to extract the content of a PKCS#7 signed file using System.Security.Cryptography.Pkcs.SignedCms?

I found this post related to pkcs#7 decrypting which suggest that there is no out of the box way to decrypt a signed pkcs#7 file. Decrypting PKCS#7 encrypted data in C#
However, I also saw this post and I managed to validate using the SignedCms class. http://blogs.msdn.com/b/shawnfa/archive/2006/02/27/539990.aspx
At the end of the post though, extracting the data using cms.ContentInfo.Content seems to return the signed file (.zip.p7) instead of the actual content (.zip). Am I missing something here? Using bouncy castle, I was able to get the actual data but would rather not use a third party if it's not necessary.
static void Main(string[] args)
{
var encodedFile = File.ReadAllBytes(InPath);
var signedData = new SignedCms();
signedData.Decode(encodedFile);
signedData.CheckSignature(true);
if (!Verify(signedData))
throw new Exception("No valid cert was found");
var trueContent = new CmsSignedData(File.ReadAllBytes(InPath)).SignedContent;
using (var str = new MemoryStream())
{
trueContent.Write(str);
var zip = new ZipArchive(str, ZipArchiveMode.Read);
zip.ExtractToDirectory(OutPath);
}
//using (var str = new MemoryStream(signedData.ContentInfo.Content))
//{
// var zip = new ZipArchive(str, ZipArchiveMode.Read);
// zip.ExtractToDirectory(OutPath);
//}
}
static bool Verify(SignedCms signedData)
{
var myCetificates = new X509Store(StoreName.My, StoreLocation.LocalMachine);
myCetificates.Open(OpenFlags.ReadOnly);
var certs = signedData.Certificates;
return (from X509Certificate2 cert in certs
select myCetificates.Certificates.Cast<X509Certificate2>()
.Any(crt => crt.Thumbprint == cert.Thumbprint))
.Any();
}
UPDATE: Will get back with the base64 sample file. Need to come up with one that doesn't contain sensitive information.
UPDATE: Here is the base 64 version of a file I can extract using bouncy castle but not using the ContentInfo.Content property. I've added as a comment on the code how I would extract SignedCms directly.
MIIFfQYJKoZIhvcNAQcCoIIFbjCCBWoCAQExCzAJBgUrDgMCGgUAMIHOBgEAoIHIBIHFUEsDBBQAAAAIAGRuWEggPN74JwAAADsAAAAMAAAAdGVzdGRhdGEudHh0bcixDQAgCEXB3sQd/gq6EVFaLHz7hwHgysM/uobpvMCDOUppdbkTUEsBAj8AFAAAAAgAZG5YSCA83vgnAAAAOwAAAAwAJAAAAAAAAAAgAAAAAAAAAHRlc3RkYXRhLnR4dAoAIAAAAAAAAQAYAOAo0XGdbtEBktqpaZ1u0QGS2qlpnW7RAVBLBQYAAAAAAQABAF4AAABRAAAAAACgggL7MIIC9zCCAd+gAwIBAgIQN3SCtKd9Hp1BDqeyqVr+tjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwdmb28uYmFyMB4XDTE2MDIyNDAwNDg0MFoXDTM5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJcGtjczdzaWduMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh5KDyFhPcxueQ1vJ0yQpcAyrSHLKw/Y2K0qhZfa7W3A6q33/i8VLl0XOFCCJs+iwcJcC+iCOIw+fFkRUEj9d7Z1sKwBCcZMolkZtNvtdXOgphV6R3g6/QNZgiQ3FFqHgp7+5OAdtBEsfsoowOClnVqZAmXnXW3Pl6Lsx0wxI8A7huytqboKRqrbRz02xO9rR1Ism0g5uQBtB2rpqGQk6/1ti/UYCp9fx7pxvWhe+a+oNIq7+ijAHPNLC+bwQTGd3LhwkzMSdONpY/utdbqCqToq/IbQ7KM0NRExZL/egPCsyJ2GGBQOVCveKkzdsW5V8p2XljcI5Sq7V8lVtqR3unwIDAQABo0cwRTBDBgNVHQEEPDA6gBBZ/6xjvqs3BLMBnQj5XmOJoRQwEjEQMA4GA1UEAxMHZm9vLmJhcoIQCiUdhpq5qrlA3FTAf3hpsTANBgkqhkiG9w0BAQsFAAOCAQEAcYl//1mzJa62K5uR+8CrpsrPWHEJ1H8l25CUQGL3u4g+ANOvJsJR6nryo4us9nI7XPocJNnFCoj26qfNmWgIF5giGkQpU2gRV5bPvYc6nPj4jZaQ7RcxJ4FT1BN/3ue7NLREodO/E1J2YWKE3uOLreBikn5B6tPKPEzA8XTjVB0ZZzfu7LMvsltB2fcaEbsifVCt4hlbtWlgFuNCbidIRWMpg8NdwcWydR1C7kuKGh1LJDG0v3ZPRgytkie8l/9zqvki4wt/kWXmDwba0lCWoyrfyahGMq5u2cqLG45pk/+1L89nw3BfR1U+5b786iXgNXKmYRWchwMQQ9r1xEa5FTGCAYYwggGCAgEBMCYwEjEQMA4GA1UEAxMHZm9vLmJhcgIQN3SCtKd9Hp1BDqeyqVr+tjAJBgUrDgMCGgUAoDcwEAYJKoZIhvcNAQkDMQMGAQAwIwYJKoZIhvcNAQkEMRYEFGmRdgvd3g6DeMqXK0QfUmJq7UnFMA0GCSqGSIb3DQEBAQUABIIBAEKdfeAfyc5TAei/GWW6Ns6aAvOrVXqNkkOJessd9P2ZYSxG4CTOo300jea7o2DYruiC4FJnSPqH7NoI0Q8EAod/E7HevZnrUq2Rtga4hSZSJfgnQuJqrOJksWfysRqt86cfwQYqmlSd94e7CgmT293rGTbG8SdXxRA8qi2J+2OULVSBFi3Z1x0hQlf31ioVBl5WMchsM8ri/q9IBBwFGqdEKVqxcmLkEtVv3czCq1z6rqkXkDk/qZ7qlhDzAqn8uguoXqhOR075Hv3Qnz6j1R+220aCOq5CmZIzdk8o8arEA9siXUASjbQpzULpG5fAenlCrgCnAXBkzkJKsBaTbYY=

Categories