我使用算法ECDSA在.net 6中实现了使用特定私钥对xml文档进行签名的代码
曲线secp256k1 my.net6代码:
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);
它对我来说很好
但问题是,我需要使用4.7.net框架进行同样的实现,我尝试了这个
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);
现在我面临的几个问题
1-我在命名曲线中找不到secp256k1
2-它抛出错误,因为Q.x、Q.y、D的长度不相同
3-我使用的证书包括我的公钥
注意,我的私钥存储为base64字符串
那么,有办法让它发挥作用吗?我走的路对吗?
有没有将这个keyString附加到X509Cetricate2对象并使用
signer.SigningKey = X509Cetrifcate2.Privatekey;
而不是
signer.SigningKey = key;
它行得通吗?
请让我知道
嗨,我找到了我的问题的解决方案,它是两个解决方案的混合第一个(找不到原始链接,请重新引用(这是一段代码片段,用于导入我的私钥并生成签名(使用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);
这部分用于在规范化后生成xml摘要
加载我的xml并应用规范化,并以字节形式获得输出:
XmlDocument invoice = new XmlDocument();
invoice.LoadXml(doc);
XmlDsigC14NTransform t = new XmlDsigC14NTransform();
t.LoadInput(invoice);
Stream invoiceStream = (Stream)t.GetOutput(typeof(Stream));
最后得到了我的InvoiceDigest
SHA256Cng sHA256 = new SHA256Cng();
byte[] hash = sHA256.ComputeHash(invoiceStream);
invoiceDigestValue = Convert.ToBase64String(hash);