使用x509证书签名json文档或字符串

本文关键字:文档 字符串 json x509 证书 书签 使用 | 更新日期: 2023-09-27 18:16:36

如何使用x509证书签署json文档或字符串?

public static void fund()
{
    string filePath = @"C:'Users'VIKAS'Desktop'Data.xml";
    //Read the file    
    XmlDocument xmlDoc = new XmlDocument();
    XElement ele = XElement.Load(filePath);
    String Xml = ele.ToString();
    xmlDoc.LoadXml(Xml);
    string signature = SignedXMLCert(xmlDoc);
    bool verified = ValidateSignature(signature);
}
public static string SignedXMLCert(XmlDocument xmlDoc)
{
    string startupPath = AppDomain.CurrentDomain.BaseDirectory + @"Certificates'unidesk.p12";
    //  startupPath = AppDomain.CurrentDomain.BaseDirectory + @"'Certificates'BBPS_enc.cer";
    //X509Certificate2 cert = new X509Certificate2(@"D:'Sonal'AXISOU_TEST.P12", "axisbank", X509KeyStorageFlags.Exportable);
    X509Certificate2 cert = new X509Certificate2(startupPath, "axisbank", X509KeyStorageFlags.Exportable);
    //  string PrivateKey = GetRSAPrivateKeyBase64(cert);
    var privateKey = cert.PrivateKey as RSACryptoServiceProvider;
    SignedXml signedXml = new SignedXml(xmlDoc);
    signedXml.SigningKey = privateKey;
    // Create a reference to be signed.
    Reference reference = new Reference();
    reference.Uri = "";
    KeyInfo keyInfo = new KeyInfo();
    //startupPath = AppDomain.CurrentDomain.BaseDirectory + @"'Certificates'BBPS_enc.cer";
    X509Certificate MSCert = new X509Certificate(startupPath, "axisbank", X509KeyStorageFlags.Exportable);
    // X509Certificate MSCert = X509Certificate.CreateFromCertFile(startupPath);
    keyInfo.AddClause(new KeyInfoX509Data(MSCert));
    signedXml.KeyInfo = keyInfo;

    // Add an enveloped transformation to the reference.
    XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
    reference.AddTransform(env);
    // Add the reference to the SignedXml object.
    signedXml.AddReference(reference);
    // Compute the signature.
    signedXml.ComputeSignature();
    // Get the XML representation of the signature and save
    // it to an XmlElement object.
    XmlElement xmlDigitalSignature = signedXml.GetXml();
    // Append the element to the XML document.
  xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    return xmlDoc.InnerXml.ToString();
}
public static bool ValidateSignature(String signedServiceMetadataContent)
{
    bool result = false;
    X509Certificate2 cert = GetCertificate();
    //Load the key
    CspParameters csp = new CspParameters();
    csp.KeyContainerName = cert.PublicKey.Key.ToString();
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
    //Load XML document
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.PreserveWhitespace = true;
    xmlDocument.LoadXml(signedServiceMetadataContent);
    //create a SignedXml and load the xml document
    SignedXml signedXml = new SignedXml(xmlDocument);
    //find signature and create signature node list
    XmlNodeList xmlNodeList = xmlDocument.GetElementsByTagName("Signature");
    if (xmlNodeList.Count <= 0)
    {
        throw new CryptographicException("Verification failed: No Signature was found in the document.");
    }
    // if more than one signature was found.
    if (xmlNodeList.Count >= 2)
    {
        throw new CryptographicException("Verification failed: More that one signature was found for the document.");
    }
    //Load signature into SignedXml
    signedXml.LoadXml((XmlElement)xmlNodeList[0]);
    //check the signature
    result = signedXml.CheckSignature(cert, true);
    //result = signedXml.CheckSignature(rsa);

    return result;
}
private static X509Certificate2 GetCertificate()
{
    string startupPath = AppDomain.CurrentDomain.BaseDirectory + @"Certificates'unidesk.p12";
    X509Certificate2 cert = new X509Certificate2(startupPath, "axisbank", X509KeyStorageFlags.Exportable);
    return new X509Certificate2(cert);
}

使用x509证书签名json文档或字符串

XMLDsig签名格式只适用于XML文档。您可以应用JSON Web签名(JWS),这是为JSON文档设计的。

jw签名

具有紧凑序列化的JWS表示为(见RFC7515)

BASE64URL(UTF8(JWS Protected Header)) || '.' ||
BASE64URL(JWS Payload) || '.' ||
BASE64URL(JWS Signature)

JWS保护头文件

最简单的标头由alg组成。RS256表示SHA-256的RSA算法

{"alg":"RS256"}

可以添加其他参数,如x5c (X.509证书链)或cty(内容类型)

jw载荷

有效负载是编码为base64url的JSON对象

eyJ1cGRhdGVTUlJlcSI6IHsgImluY2lkZW50SUQiOiAiIiwgImNyZWF0ZWRCeSI6ICIwMzcwMjIwMDAwNDIwNDgiLCAiZGVzY3JpcHRpb24iOiAiMDM3MDIyMDAwMDQyMDQ4IiwgImlzVmlzaWJsZVRvQ3VzdG9tZXIiOiAiMyIsICJ1cGRhdGVUeXBlIjogIjIiLCAiYWN0aXZpdHlUeXBlIjogIjIiLCAiY3JlYXRlZE9uIjogIjIwMTYtMDktMDggMTc6NTciLCAibGFzdFVwZGF0ZSI6ICIyMDE2LTA5LTA4IDE3OjU3IiwgInN0YXR1cyI6ICIyIiwgImNsb3NlZFRpbWUiOiAiIiB9LCAic3ViSGVhZGVyIjogeyAidmFsdWUiOiB7ICJyZXF1ZXN0VVVJRCI6ICIxMjMiLCAiU2VydmljZVJlcXVlc3RJZCI6ICJBRS5NQVBTLlVESy5TU1RQIiwgIlNlcnZpY2VSZXF1ZXN0VmVyc2lvbiI6ICIxLjAiLCAiQ2hhbm5lbElkIjogIk1BUFMifX19
<<p> jw签名/strong>

上计算JWS签名
BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload))

构建以下字符串并使用证书的私钥应用RSA数字签名算法

eyJhbGciOiJSUzI1NiJ9.eyJ1cGRhdGVTUlJlcSI6IHsgImluY2lkZW50SUQiOiAiIiwgImNyZWF0ZWRCeSI6ICIwMzcwMjIwMDAwNDIwNDgiLCAiZGVzY3JpcHRpb24iOiAiMDM3MDIyMDAwMDQyMDQ4IiwgImlzVmlzaWJsZVRvQ3VzdG9tZXIiOiAiMyIsICJ1cGRhdGVUeXBlIjogIjIiLCAiYWN0aXZpdHlUeXBlIjogIjIiLCAiY3JlYXRlZE9uIjogIjIwMTYtMDktMDggMTc6NTciLCAibGFzdFVwZGF0ZSI6ICIyMDE2LTA5LTA4IDE3OjU3IiwgInN0YXR1cyI6ICIyIiwgImNsb3NlZFRpbWUiOiAiIiB9LCAic3ViSGVhZGVyIjogeyAidmFsdWUiOiB7ICJyZXF1ZXN0VVVJRCI6ICIxMjMiLCAiU2VydmljZVJlcXVlc3RJZCI6ICJBRS5NQVBTLlVESy5TU1RQIiwgIlNlcnZpY2VSZXF1ZXN0VmVyc2lvbiI6ICIxLjAiLCAiQ2hhbm5lbElkIjogIk1BUFMifX19 

最后将签名编码为base64url,并将结果附加到前面要签名的数据中。你会得到这样一个JWS: hhhhh.ppppp.sssss,其中hhhhh是报头,ppppp是有效载荷,sssss是签名

使用以下链接到

  • Base64url encoding:解码/编码修改后的base64 URL的代码
  • 用。net和证书(c#)签名和验证签名: https://blogs.msdn.microsoft.com/alejacma/2008/06/25/how-to-sign-and-verify-the-signature-with-net-and-a-certificate-c/

jw验证

验证来自压缩格式hhhhh.ppppp.sssss的签名,base64url解码签名sssss,并使用签名数据hhhhh.ppppp和使用的证书验证签名