Reputation: 17
I was implementing code for signing a xml document using specific private key in .net 6
using algorithm ECDSA with
curve secp256k1 my .net6
code :
ECDsaCng key = new ECDsaCng();
key.ImportECPrivateKey(Convert.FromBase64String(privatKey), out _);
SignedXml signer = new SignedXml(doc);
signer.SigningKey = key;
signer.KeyInfo = new KeyInfo();
KeyInfoX509Data keydata = new KeyInfoX509Data(signingCertificate);
signer.KeyInfo.AddClause(keydata);
and it works fine with me
but the problem is I need to do the same implementation using 4.7 .net framework and I tried this
ECParameters p = new ECParameters {
Curve = ECCurve.NamedCurves.nistP256,
D = Convert.FromBase64String(privatKey),
Q = new ECPoint() {
X= z.Skip(1).Take(32).ToArray(),
Y = z.Skip(33).ToArray()
}
};
ECDsaCng key = (ECDsaCng)ECDsaCng.Create(p);
SignedXml signer = new SignedXml(doc);
signer.SigningKey = key;
signer.KeyInfo = new KeyInfo();
KeyInfoX509Data keydata = new KeyInfoX509Data(signingCertificate);
signer.KeyInfo.AddClause(keydata);
now there is several problem I am facing
1- I cannot find secp256k1 in named curves
2- It throws errors as Q.x,Q.y,D are not with the same length
3- the certificate Iam using includes My public key
note my privateKey is stored as base64 string
So is there a way to make it work ? Am I on the right path?
is there any to attach this keyString to a X509Cetrifcate2 object and use
signer.SigningKey = X509Cetrifcate2.Privatekey;
instead of
signer.SigningKey = key;
Would it work ?
Please let me Know
Upvotes: 0
Views: 703
Reputation: 17
Hi I found the solution for my problem it is mix of 2 solutions first (Can not find the original Link Please reffer it ) it is this code snippet for importing my private key and Generating the signature (using Bouncy Castle)
string pkcs8 = @"-----BEGIN EC PRIVATE KEY-----
"+privatKey+@"
-----END EC PRIVATE KEY-----";
TextReader privateKeyTextReader = new StringReader(pkcs8);
AsymmetricCipherKeyPair privateKeyParams = (AsymmetricCipherKeyPair)new PemReader(privateKeyTextReader).ReadObject();
byte[] message = Encoding.UTF8.GetBytes(doc);
ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA"); // ASN.1/DER format
signer.Init(true, privateKeyParams.Private);
signer.BlockUpdate(message, 0, message.Length);
byte[] signature = signer.GenerateSignature();
signatureValue = Convert.ToBase64String(signature);
and this part for generating the xml digest after canonlization
Load my xml and apply canonlization and get the output as bytes:
XmlDocument invoice = new XmlDocument();
invoice.LoadXml(doc);
XmlDsigC14NTransform t = new XmlDsigC14NTransform();
t.LoadInput(invoice);
Stream invoiceStream = (Stream)t.GetOutput(typeof(Stream));
and finaly getting my InvoiceDigest
SHA256Cng sHA256 = new SHA256Cng();
byte[] hash = sHA256.ComputeHash(invoiceStream);
invoiceDigestValue = Convert.ToBase64String(hash);
Upvotes: 0