>
> No jak widać z powyższego nie jest to proste :)
>
Pitu Pitu
Ponieważ nie znam za dobrze C# dlatego nie skończone(skończyła się
licenicja na 2015), samemu dalej ciężko.
Używam Microsoft.XAdes z gita nie ze strony internetowej!
Należy używać NetFrameWork minimum 4.2 z uwagi na
CryptoConfig.AddAlgorithm...
Trzeba zmodyfikować aby działało AES256
do
namespace Microsoft.Xades
{
...
//trzeba dodać
public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
{
public RSAPKCS1SHA256SignatureDescription()
{
base.KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
base.DigestAlgorithm = typeof(SHA256Managed).FullName;
base.FormatterAlgorithm =
typeof(RSAPKCS1SignatureFormatter).FullName;
base.DeformatterAlgorithm =
typeof(RSAPKCS1SignatureDeformatter).FullName;
CryptoConfig.AddAlgorithm(typeof(SHA256CryptoServiceProvider), new
string[0]);
}
public override AsymmetricSignatureFormatter
CreateFormatter(AsymmetricAlgorithm key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
RSAPKCS1SignatureFormatter formatter = new
RSAPKCS1SignatureFormatter(key);
formatter.SetHashAlgorithm("SHA256");
return formatter;
}
}
}
Następnie zmienić funkcje ComputeSignature na
public new void ComputeSignature()
{
this.BuildDigestedReferences();
AsymmetricAlgorithm signingKey = base.SigningKey;
if (signingKey == null)
{
throw new
CryptographicException("Cryptography_Xml_LoadKeyFailed");
}
if (base.SignedInfo.SignatureMethod == null)
{
if (!(signingKey is DSA))
{
if (!(signingKey is RSA))
{
throw new
CryptographicException("Cryptography_Xml_CreatedKeyFailed");
}
if (base.SignedInfo.SignatureMethod == null)
{
base.SignedInfo.SignatureMethod =
"
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
}
}
else
{
base.SignedInfo.SignatureMethod =
"
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
}
}
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),
new string[]
{
"
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
});
SignatureDescription description =
CryptoConfig.CreateFromName(base.SignedInfo.SignatureMethod) as
SignatureDescription;
if (description == null)
{
throw new
CryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");
}
HashAlgorithm hash = description.CreateDigest();
if (hash == null)
{
throw new
CryptographicException("Cryptography_Xml_CreateHashAlgorithmFailed");
}
this.GetC14NDigest(hash, "ds");
this.m_signature.SignatureValue =
description.CreateFormatter(signingKey).CreateSignature(hash);
}
Następnie w zdarzeniu przycisku
private void button_Click(object sender, RoutedEventArgs e)
{
// Sign the XML that was just created and save it in a
// new file.
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "XML|*.xml";
openFileDialog1.Title = "Wybierz plik xml";
if (openFileDialog1.ShowDialog() ==
System.Windows.Forms.DialogResult.OK)
{
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly |
OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection =
(X509Certificate2Collection)store.Certificates;
X509Certificate2Collection fcollection =
(X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid,
DateTime.Now, false);
X509Certificate2Collection scollection =
X509Certificate2UI.SelectFromCollection(fcollection, "Wybierz
Certyfikat", "Proszę wskazać certyfikat do podpisu",
X509SelectionFlag.MultiSelection);
/* foreach (X509Certificate2 x509 in scollection)
{
XmlDocument doc = new XmlDocument();
byte[] rawdata = x509.RawData;
doc.PreserveWhitespace = false;
doc.Load(new
XmlTextReader(System.IO.Path.GetDirectoryName(openFileDialog1.FileName)
+ "\\initupload.xml"));
if (doc.DocumentElement == null) throw new
InvalidOperationException("Invalid XML document; no root element found.");
sign(openFileDialog1.FileName,
System.IO.Path.GetDirectoryName(openFileDialog1.FileName) +
"\\sinitupload.xml",
x509);
x509.Reset();
}
store.Close();*/
foreach (X509Certificate2 x509 in scollection)
{
signXades(openFileDialog1.FileName, x509);
//funkcja podpisująca
x509.Reset();
}
store.Close();
System.Environment.Exit(1);
}
}
w x509 mamy certyfikat pobrany z karty
następnie podpisywanie
private void signXades(string filepath, X509Certificate2 cert)
{
//string exportedKeyMaterial =
cert.PrivateKey.ToXmlString(true);
//RSACryptoServiceProvider key = new
RSACryptoServiceProvider(new CspParameters(24));
//key.PersistKeyInCsp = false;
// key.FromXmlString(cert.PrivateKey.ToXmlString(true)); //=
cert.PrivateKey;// .FromXmlString(exportedKeyMaterial);
XadesSignedXml signedXml = new XadesSignedXml(this.doc);
signedXml.Signature.Id = "id-1234";
signedXml.SigningKey = cert.PrivateKey;
signedXml.SignedInfo.CanonicalizationMethod =
"
http://www.w3.org/2001/10/xml-exc-c14n#";
signedXml.SignedInfo.SignatureMethod =
"
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
Reference reference = new Reference();
reference.Id = "r-id-1";
reference.Uri = "";
reference.Type = "";
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.AddTransform(CreateXPathTransform("not(ancestor-or-self::Signature)"));
reference.DigestMethod =
"
http://www.w3.org/2001/04/xmlenc#sha256";
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
Cert xadesCert = new Cert();
xadesCert.IssuerSerial.X509IssuerName =
cert.IssuerName.Name;
xadesCert.IssuerSerial.X509SerialNumber = cert.SerialNumber;
xadesCert.CertDigest.DigestMethod.Algorithm =
"
http://www.w3.org/2001/04/xmlenc#sha256";
xadesCert.CertDigest.DigestValue =
CryptHelper.Sha1(cert.RawData);
XadesObject xades = new XadesObject();
xades.QualifyingProperties.Target = string.Format("#{0}",
signedXml.Signature.Id);
xades.QualifyingProperties.SignedProperties.Id =
string.Format("xades-{0}",
signedXml.Signature.Id);
xades.QualifyingProperties.SignedProperties.SignedSignatureProperties.SigningTime
= DateTime.Now;
xades.QualifyingProperties.SignedProperties.SignedSignatureProperties.SignaturePolicyIdentifier.SignaturePolicyImplied
= true;
xades.QualifyingProperties.SignedProperties.SignedSignatureProperties.SigningCertificate.CertCollection.Add(xadesCert);
//xades.QualifyingProperties.SignedProperties.SignedSignatureProperties.SignaturePolicyIdentifier
= new SignaturePolicyIdentifier();
DataObjectFormat fmt = new DataObjectFormat();
fmt.ObjectReferenceAttribute = string.Format("#{0}",
reference.Id);
fmt.MimeType = "text/xml";
xades.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormatCollection.Add(fmt);
signedXml.AddXadesObject(xades);
signedXml.ComputeSignature();
this.doc.DocumentElement.AppendChild(signedXml.GetXml());
//this.doc.Save(filepath);
XmlElement xmlDigitalSignature = signedXml.GetXml();
string filetosave =
System.IO.Path.GetDirectoryName(filepath) + "\\sinitupload.xml";
XmlTextWriter xmltw = new XmlTextWriter(filetosave, new
UTF8Encoding(false));
doc.WriteTo(xmltw);
xmltw.Close();
}
Plik w ten sposób podpisany wysłany do bramki komunikat
"podpis nie jest w formacie xades-base"
Kod jest do ogólnego dostępu i wykorzystania.
w zamian oczekuję na publiczne wskazanie dlaczego nie działa i
poprawienie oraz publikację na tym forum poprawnego rozwiązania.
Na pohybe firmom żądającym za kilkanaście linijek kodu 5000zł, to nie żart.