I'm working with some web-service which requires digitally signed XML to be posted via HTTP post request.
They gave me only one file (key.dat) which I should apply to my XML.
How can I do it?
You can take a look over here:
private static XmlElement GetXmlDigitalSignature(XmlDocument x, AsymmetricAlgorithm key)
{
var signedXml = new SignedXml(x) { SigningKey = key };
var reference = new Reference { Uri = "", TransformChain = new TransformChain(), };
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
signedXml.AddReference(reference);
signedXml.ComputeSignature();
return signedXml.GetXml();
}
var signature = GetXmlDigitalSignature(xmlDocument, algorithm);
xmlDocument.FirstChild.AppendChild(xmlDocument.ImportNode(signature, true));
Related
I'm creating a code that verifies the signature of an xml file through the public key of the certification authority of the certificate that signed that xml. For some reason when I check with the public key of the certificate that signed it, everything goes well, but when I use the public key of the parent, it says that the signature is invalid.
I show below both the code that signs and what it verifies.
Comments:
The CA is self-signed by an AD CS.
I don't want the crl of the certificates to be validated.
private void signBtn_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\urnaData\votos.xml");
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByIssuerName, "CA das Urnas - CNE", true);
foreach (X509Certificate2 x509 in col)
{
SignXmlDoc(doc, x509);
File.WriteAllText(#"C:\urnaData\votes-signed.xml", doc.OuterXml);
}
store.Close();
}
public static void SignXmlDoc(XmlDocument doc, X509Certificate2 cert)
{
SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = cert.GetRSAPrivateKey();
Reference reference = new Reference();
reference.Uri = "";
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
XmlElement xmlSig = signedXml.GetXml();
doc.DocumentElement.AppendChild(doc.ImportNode(xmlSig, true));
}
private void testSign_Click(object sender, EventArgs e)
{
X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByIssuerName, "CA das Urnas - CNE", true);
foreach (X509Certificate2 x509 in col)
{
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\urnaData\votes-signed.xml");
MessageBox.Show(ValidateXMLSignature(doc, x509).ToString());
}
store.Close();
}
public static bool ValidateXMLSignature(XmlDocument doc, X509Certificate2 cert)
{
try
{
SignedXml signedXml = new SignedXml(doc);
XmlNode signatureNode = doc.GetElementsByTagName("Signature")[0];
signedXml.LoadXml((XmlElement)signatureNode);
return signedXml.CheckSignature(cert, true);
}
catch
{
return false;
}
}
For some reason when I check with the public key of the certificate that signed it, everything goes well, but when I use the public key of the parent, it says that the signature is invalid.
That sounds like everything is working correctly. The parent/CA didn't sign the document, so their public key can't verify it. All you can do is ask two different questions:
Does /this/ certificate's public key verify the signature.
Does /this/ certificate's issuance chain (see X509Chain) say that /this other/ certificate was its direct issuer? (s_parentCertBytes.SequenceEqual(chain.ChainElements[1].Certificate.RawData))
If both return true, then you have effectively written an issuer-pinning routine. But you can't do it without the public key of the actual signing certificate. (The easiest way to internalize that is to realize that the CA and the issued cert don't need to use the same algorithm family... e.g. the CA could have an ECDSA-based key and the issued cert have an RSA-based key... so there's no way you can sensibly ask if the ECDSA public key of the CA can corroborate the RSA signature.)
I am creating signed SAML Request using below code and the certificates are cross checked to be same however getting invalid signature error on IDP , Please suggest
public XmlDocument SignXML(XmlDocument xml)
{
X509Certificate2 cert = new X509Certificate2(#"" + SPCertificateLocation, SPCertificatePassword);// , X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
// set key, signing algorithm, and canonicalization method
var signedXml = new SignedXml(xml.DocumentElement) { SigningKey = cert.GetRSAPrivateKey() };
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
//signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
// sign whole document using "SAML style" transforms
var reference = new Reference { Uri = string.Empty };
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoData = new KeyInfoX509Data(cert);
keyInfo.AddClause(keyInfoData);
signedXml.KeyInfo = keyInfo;
// create signature
signedXml.ComputeSignature();
// get signature XML element and add it as a child of the root element
//signedXml.GetXml();
//XmlElement xmlSignature = signedXml.GetXml();
//AssignNameSpacePrefixToElementTree(xmlSignature, "ds");
// Add prefix "ds:" to signature
XmlElement signature = signedXml.GetXml();
SetPrefix("ds", signature);
// Load modified signature back
signedXml.LoadXml(signature);
// this is workaround for overcoming a bug in the library
signedXml.SignedInfo.References.Clear();
// Recompute the signature
signedXml.ComputeSignature();
string recomputedSignature = Convert.ToBase64String(signedXml.SignatureValue);
// Replace value of the signature with recomputed one
ReplaceSignature(signature, recomputedSignature);
// Append the signature to the XML document.
xml.DocumentElement.InsertAfter(xml.ImportNode(signature, true), xml.DocumentElement.FirstChild);
//xml.DocumentElement?.AppendChild(signedXml.GetXml());
return xml;
}
The code converts the XML correctly into signature enabled XML however it is showing unable to verify the authenticity of signature
<saml2p:AuthnRequest ID="_3a6d2566-68a1-4afc-a784-c125bd94173f" Version="2.0" ForceAuthn="false" IssueInstant="2022-05-09T08:26:33Z" Destination="https://auth.pingone.com/172e7894-5cbe-456b-b451-d2585aeab74f/saml20/idp/sso" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="http://localhost:20630/CASCC/SamlConsume" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:20630</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><ds:Reference URI=""><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><ds:DigestValue>EZBisrHSVKE2zS15roaUFG0EnP3ZobisulcQXw0fO18=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>uyniiynlIP6z/g6U4qzWKdmeD8sP7majYwqDhy5n2nTDJyE8MEdaIhEJssIDeuc+VAILueMhzRV/mC4uiAZ5kgAYDa0LYnaO3673dCvuFJPgQxKbJUWYSTnfY89x/VYXsFm6kKgR2pxyGgq4VYGK9W/vvpIi+PKkYwCKtjjb8LKin/zoCPAA7UecMS9mxPeJ/ntdEfjIGTwBcoETsFRRNdVToTdVtQJjc4LBa/5FnJbGNRKFIdRDqx+wr7IbaT+08o5yl+UI2Qogly8JxeOPolVUr94rLXKyY1/n2nkXr+5LoY/sRomoCNJ11wLsMUEmg11j4J3bB93FGtlnmpwm4Q==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIEFzCCAv+gAwIBAgIUeUS7jZnkZLcxjRUQ5uhqrAI7z2gwDQYJKoZIhvcNAQELBQAwgZoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTEPMA0GA1UEBwwGQm9zdG9uMRQwEgYDVQQKDAtDb21tYW5kQ29tbTEUMBIGA1UECwwLQ29tbWFuZENvbW0xFDASBgNVBAMMC0NvbW1hbmRDb21tMSswKQYJKoZIhvcNAQkBFhxha2Fwb29yQGNvbW1hbmRjb21wYW5pZXMuY29tMB4XDTIyMDQxNTExNDk1MloXDTIzMDQxNTExNDk1MlowgZoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTEPMA0GA1UEBwwGQm9zdG9uMRQwEgYDVQQKDAtDb21tYW5kQ29tbTEUMBIGA1UECwwLQ29tbWFuZENvbW0xFDASBgNVBAMMC0NvbW1hbmRDb21tMSswKQYJKoZIhvcNAQkBFhxha2Fwb29yQGNvbW1hbmRjb21wYW5pZXMuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyTHXlPSUCzHLGXkoSkuXTh2/oONTe+5TcswtFTnq6VDZnZ3m1tNs2EWcOXq6lVjSlfaqByCHUSGa0O54qMAD2WdZjTv08GQS1uYtJhjQvi58P32ost2LBEKYhtyaw8fen81OwJq+tiDHCw8xrx/z610rHGQVRrSojmqC6zLOclkQmrfpAhC2L+enovxfl6xW0FzYJETFYv/jW0ACcaZJBtFb7AfYDlCzvajUQ+dGTpZE1/0UOGdOTNjbMezGxFDyndcJ4ZLQItbG0cE3c1fEQkU06OYgPoOeXGsHM2w1R498oS/pk1ZLB1LtDUfKl7PVmjJGoytCi38Huft/95u0JQIDAQABo1MwUTAdBgNVHQ4EFgQUawg+tyAVohufNTVu7RXqPtu+B4MwHwYDVR0jBBgwFoAUawg+tyAVohufNTVu7RXqPtu+B4MwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAPom0ZUQx3OWXlO7R5Goyv7cEepq+Nikd82chqzUvwhXW5Azb3xsC+cgh0srjYlrRC9QJk7m43yQE1xa0DM4aKi/rA/l9rLJpXfjQj+97V0SA8JMrCxbcxdN+v2mN1vp8xprJ2i+nPtCBPqLM2XA0kUQ44zeygCm+L78zElYu79r3YF6ObzA9D3/Fa794zFWqI/1ggmOdI4T3kzUgFxv1YMTYZ8rgWcICVs1mSU2zkT5ScJq0NJPENR0jpzFHzirzIJUgnAcOWnCnzyCKDgpJI/+9yJNzLaR97LHk12cVfQMuBvLcchRian08sZ/J4a440h54bB9EByp+853rUpHhVQ==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></saml2p:AuthnRequest>
As #timothy suggested i added the Id = "#" + Id
and below is the XML generated
<saml2p:AuthnRequest ID="_35ab8f46-0ba1-4a29-a153-b02e97bf1397" Version="2.0" ForceAuthn="false" IssueInstant="2022-05-10T09:25:33Z" Destination="https://auth.pingone.com/172e7894-5cbe-456b-b451-d2585aeab74f/saml20/idp/sso" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="http://localhost:20630/CASCC/SamlConsume" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:20630</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><ds:Reference URI="#_35ab8f46-0ba1-4a29-a153-b02e97bf1397"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><ds:DigestValue>0iGmT3qeJrHVXJveUe5AboRo65hxD25OjVpbbxWvbUo=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>InYJ2yGLSnL9Q2BVaWBfABpcpiViFgZH6XnvhYU0I67sPI/KTb6g39MZMBM4XiUDNTpjGXHcZn9c2elh+NnVAx/SPX8R0Yjq7dKiVe+Zz6BFKk0DCSA9Q2APFCk2uJZVlvKza3tIjoxrBvQuxZcNZxsMOUm8LEWnhQ3ElgN7pisHj5AiAzc/VluPIl21BG+tTolV/Ab7bg+B7YdBwK4++QEyK0R7dsYoZex+NsLf1+zel1xWg2PbZgTXOi4PXFB9RvIPXDUtfMPCSOUQRUdgbI6GeV5X+ZWCGOs0m0FnnZD7hL1WR1sWOcHUgY0DSIpgtToJintjx0f5HphidWZF9/sjP+zR9QEOtkcBMYl9JacO5tbNp49fZSVuuqN2pMxcSCE2BmPdoWw1t/CHrKFOzOfNyNQsvauP2UpufQQt+lxUePpvE7VZNuXYQ+hGv74FkBpy6NU58x3agqOP0NeMsyrT+R0AOSTCXWqzfogYIOR9t/mOFMTohKJqjPXB7H2+LrlOcmQM/+HHUf21F4KP6w2ujbFESOgCZmoyou0gBDEAtT4xbYvwnplZwSbYaKHQQhunyzesfqtdF8bY9+0jVsfj0+e7tzofoURb+d6HMtbJxDnIg4VUzmI2QHEUhNJzT1nAS2cbVieP/kGzmLQ9TKGhYdTUnWVa16oXZz+qkeo=</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIFqDCCA5ACFAQ5F+2NYAb4N/enCOaeA/V2IVPYMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYDVQQGEwJVUzELMAkGA1UECAwCVVMxCzAJBgNVBAcMAk5ZMRQwEgYDVQQKDAtDb21tYW5kQ29tbTEUMBIGA1UECwwLQ29tbWFuZENvbW0xCzAJBgNVBAMMAkNDMSswKQYJKoZIhvcNAQkBFhxha2Fwb29yQGNvbW1hbmRjb21wYW5pZXMuY29tMB4XDTIyMDUwOTEyMDcyNVoXDTIzMDUwOTEyMDcyNVowgZIxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJVUzELMAkGA1UEBwwCTlkxFDASBgNVBAoMC0NvbW1hbmRDb21tMRQwEgYDVQQLDAtDb21tYW5kQ29tbTEQMA4GA1UEAwwHQ29tbWFuZDErMCkGCSqGSIb3DQEJARYcYWthcG9vckBjb21tYW5kY29tcGFuaWVzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKoMSbgGecTY5d6bNjCEnpX2YxY+QRNDT0v/zGpO23PZlt+fuaYHr+b0hP3R/3cCxVTmd36o6MNASjT/slq8aFTdk49sW/zwICNa5AtjRRBVHGOmNYz/ntbo1KIQzC1faoGg+1CiTBL/vflQN4EWMyKGg/GfyIeKLODmOzzx41U5Y/Bv22X8bMmnFgYtwBMh2c7X0hNysqUmkc81sJ5cDgcwNbU4tu+sLslxI+1iOmmDtZBfcYmn+5vU4lFy8XZIODqN0eWpOyvH+a6r6rhAe9vIPwjWv2oh1Ktw0HE3b4JIgk/Vk4YvHKeSTjeC0biue7EF1c0sexOac5KpRhaWNxY4tmHY0dxKT1I21ls7TFd1x9E9A+n5Ff+INb9O4V0OmTrJUiXHZ44vpOi2kv1zbf2lSVFXwF6fhcb1KqxP2XQUMr7Fs6P5JUuH9h1AB5Kf7pjcrza7jjWU3LFRQzwISnJZNV+g1f62VM1S3AHpn1YFaI49Kpn9k5kuqWgGPUlIJq+9tWIy19lL6D3vzYI4yzZR4sGp8NcdSlKR8FgMgfB3bU4DtP85agoEOQ5C2DKV8No3jLVEJ8qFMhn/kLzcDy9oWF7ZVQGUmYuNo0q5T9O4dXcX0alXx0PS9UKJwfw23sGfUenwLI9HZEAqK5f3UEaDnfFmhxlajIAMj2hPldODAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAL4Fr2RzIH0O4VJRgYQr1ASeSghzijkhSHpjmL3fCEVrS7WvYtgKr3gXC5tQ/8i3Immh2aqMmbmq1gk/885frCMW76e0I1ZRfSw0ktUa04WlftVLeg9lzqPEmNKwaxzSudcR+WdEnLKrm3DHXltXqXw2yuDzy1SWGeyfZ+Lq62geahBkGWn5YoQqsxbmvhFDZNtDvinUI0GsbmTEsv9oxdWGGfl0spg6y0cO5WW/8fTh6Jrpk2RjOWcx7wUChQbv/Wu4WH9S7g78/F5HSy5hQ2PTg/CVtFXt/zScj6pxXb0Uov4/PXE7zHyLPUqtOxgasov4FurDJZaxUVNE5hu9OVLiHmw0jyU0t6myON+B4+a6I2xeWDBe1EQJyK2G22yISN6o4UILD3YL3gnl/xZoe/64sKP59RU0Gxv3pyYTpCtp+DYR8xYWzN8hVG0KHlxSypkh0TwQ7a4H4x5LOXZ5Qinr1qHgjgJY9LCAYHfvX6i+pctsd+na8ZUEPKZH/ARFz1LDx0RS5RbZhsnyn7GkpJZEuUUeS+aOYkuFLlvBopcKnP8KmKXjjRmrhHaNhPhnK8cJgai377uNk87xUt2WnMankROZajIK+7M6xMTq5WgmmDPE16o6zp+mdn5I8RzglelDFtgCAf9Hz2vupH4v8fcg772fzIf277zZpl8RZc36</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></saml2p:AuthnRequest>
However when i try to validate it using https://tools.chilkat.io/xmlDsigVerify.cshtml
I get valid signature but https://console.pingone.com/ says invalid signature so may be certificates is the one i suggest it is blocking something please suggest
My Latest code looks like
public XmlDocument SignXML(XmlDocument xml)
{
X509Certificate2 cert = new X509Certificate2(#"" + SPCertificateLocation, SPCertificatePassword);// , X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
// set key, signing algorithm, and canonicalization method
var signedXml = new SignedXml(xml.DocumentElement) { SigningKey = cert.GetRSAPrivateKey() };
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
//signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
// sign whole document using "SAML style" transforms
var reference = new Reference { Uri = "#"+_id };
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoData = new KeyInfoX509Data(cert);
keyInfo.AddClause(keyInfoData);
signedXml.KeyInfo = keyInfo;
// create signature
signedXml.ComputeSignature();
// get signature XML element and add it as a child of the root element
//signedXml.GetXml();
//XmlElement xmlSignature = signedXml.GetXml();
//AssignNameSpacePrefixToElementTree(xmlSignature, "ds");
// Add prefix "ds:" to signature
XmlElement signature = signedXml.GetXml();
SetPrefix("ds", signature);
// Load modified signature back
signedXml.LoadXml(signature);
// this is workaround for overcoming a bug in the library
signedXml.SignedInfo.References.Clear();
//var reference2 = new Reference { Uri = "#" + _id };
//reference2.AddTransform(new XmlDsigEnvelopedSignatureTransform());
//reference2.AddTransform(new XmlDsigExcC14NTransform());
//signedXml.AddReference(reference2);
// Recompute the signature
signedXml.ComputeSignature();
string recomputedSignature = Convert.ToBase64String(signedXml.SignatureValue);
// Replace value of the signature with recomputed one
ReplaceSignature(signature, recomputedSignature);
// Append the signature to the XML document.
xml.DocumentElement.InsertAfter(xml.ImportNode(signature, true), xml.DocumentElement.FirstChild);
//xml.DocumentElement?.AppendChild(signedXml.GetXml());
return xml;
}
I was able to validate your XML with perl's XML::Sig after a few changes that I had to make to XML::Sig since it does not currently support SignedInfo without an ID.
https://tools.chilkat.io/xmlDsigVerify.cshtml also validates it fine so the issue is likely in your validation code that you did not show.
I am using the following code, which I borrowed originally from the jwt-dotnet github page
private static string CreateToken(UserPrincipal principal)
{
/*
* https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
* http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html
*/
var key = ConfigurationManager.AppSettings["jwt-key"];
var claims = new Dictionary<string, string>()
{
{ClaimTypes.Name, "Rainbow Dash" },
{ClaimTypes.WindowsAccountName, "RDash"}
};
var algorithm = new HMACSHA256Algorithm();
var serializer = new JsonNetSerializer();
var urlEncoder = new JwtBase64UrlEncoder();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var token = encoder.Encode(claims, key);
return token;
}
The above code generates the following token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiUmFpbmJvdyBEYXNoIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy93aW5kb3dzYWNjb3VudG5hbWUiOiJSRGFzaCJ9.5WZWDJ0pvTe6QLjVNUeTfZicX_wSsk1dtYvXUbpiOiw
So, I hopped over to jwt.io to test my token. I'm told I have an invalid signature.
How do I give it a valid 'signature'? I don't understand what my JWT is missing.
The tool over JWT.io can verify the digital signature of your token if you give it the secret signing key you used while creating a token:
And from looking at your code it's the value contained in your:
ConfigurationManager.AppSettings["jwt-key"];
Just input the value inside the "secret" text box and if the signature of the token matches the one calculated by JWT.io then you'll get a message saying that the signature is valid.
I am using the following code, which I borrowed originally from the jwt-dotnet github page
private static string CreateToken(UserPrincipal principal)
{
/*
* https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
* http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html
*/
var key = ConfigurationManager.AppSettings["jwt-key"];
var claims = new Dictionary<string, string>()
{
{ClaimTypes.Name, "Rainbow Dash" },
{ClaimTypes.WindowsAccountName, "RDash"}
};
var algorithm = new HMACSHA256Algorithm();
var serializer = new JsonNetSerializer();
var urlEncoder = new JwtBase64UrlEncoder();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var token = encoder.Encode(claims, key);
return token;
}
The above code generates the following token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiUmFpbmJvdyBEYXNoIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy93aW5kb3dzYWNjb3VudG5hbWUiOiJSRGFzaCJ9.5WZWDJ0pvTe6QLjVNUeTfZicX_wSsk1dtYvXUbpiOiw
So, I hopped over to jwt.io to test my token. I'm told I have an invalid signature.
How do I give it a valid 'signature'? I don't understand what my JWT is missing.
The tool over JWT.io can verify the digital signature of your token if you give it the secret signing key you used while creating a token:
And from looking at your code it's the value contained in your:
ConfigurationManager.AppSettings["jwt-key"];
Just input the value inside the "secret" text box and if the signature of the token matches the one calculated by JWT.io then you'll get a message saying that the signature is valid.
I am working with digital signature. We have to generate xml request and sign the request using private key. The private key to be taken from etoken which is non exportable. My findings showed that private key cannot be extracted when it is marked as non exportable. In this case, how can I sign the xml request. Please help.
Finally I got the solution. Took a while as the requirement was bit rare. This link https://www.codeproject.com/Articles/240655/Using-a-Smart-Card-Certificate-with-NET-Security-i helped me to get the solution. Please refer to below code. For SignXml() method, please refer this msdn link https://msdn.microsoft.com/en-us/library/ms229745(v=vs.110).aspx
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.MaxAllowed);
// find cert by thumbprint
var foundCerts = store.Certificates.Find(X509FindType.Thumbprint, "12345", true);
if (foundCerts.Count == 0)
return;
var certForSigning = foundCerts[0];
store.Close();
// prepare password
var pass = new SecureString();
var passwordstring = "password";
var chararr = passwordstring.ToCharArray();
foreach (var i in chararr)
pass.AppendChar(i);
// take private key
var privateKey = certForSigning.PrivateKey as RSACryptoServiceProvider;
// make new CSP parameters based on parameters from current private key but throw in password
CspParameters cspParameters = new CspParameters(1,
privateKey.CspKeyContainerInfo.ProviderName,
privateKey.CspKeyContainerInfo.KeyContainerName,
new System.Security.AccessControl.CryptoKeySecurity(),
pass);
RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider(cspParameters);
XmlDocument xmlDoc = new XmlDocument();
// Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load(path);
// Sign the XML document.
SignXml(xmlDoc, rsaCryptoServiceProvider);