public void ImportKeyNode() { string value = "<KeyInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><KeyName>Mono::</KeyName><KeyValue xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><DSAKeyValue><P>rjxsMU368YOCTQejWkiuO9e/vUVwkLtq1jKiU3TtJ53hBJqjFRuTa228vZe+BH2su9RPn/vYFWfQDv6zgBYe3eNdu4Afw+Ny0FatX6dl3E77Ra6Tsd3MmLXBiGSQ1mMNd5G2XQGpbt9zsGlUaexXekeMLxIufgfZLwYp67M+2WM=</P><Q>tf0K9rMyvUrU4cIkwbCrDRhQAJk=</Q><G>S8Z+1pGCed00w6DtVcqZLKjfqlCJ7JsugEFIgSy/Vxtu9YGCMclV4ijGEbPo/jU8YOSMuD7E9M7UaopMRcmKQjoKZzoJjkgVFP48Ohxl1f08lERnButsxanx3+OstFwUGQ8XNaGg3KrIoZt1FUnfxN3RHHTvVhjzNSHxMGULGaU=</G><Y>LnrxxRGLYeV2XLtK3SYz8RQHlHFZYrtznDZyMotuRfO5uC5YODhSFyLXvb1qB3WeGtF4h3Eo4KzHgMgfN2ZMlffxFRhJgTtH3ctbL8lfQoDkjeiPPnYGhspdJxr0tyZmiy0gkjJG3vwHYrLnvZWx9Wm/unqiOlGBPNuxJ+hOeP8=</Y><J>9RhE5TycDtdEIXxS3HfxFyXYgpy81zY5lVjwD6E9JP37MWEi80BlX6ab1YPm6xYSEoqReMPP9RgGiW6DuACpgI7+8vgCr4i/7VhzModJAA56PwvTu6UMt9xxKU/fT672v8ucREkMWoc7lEey</J><Seed>HxW3N4RHWVgqDQKuGg7iJTUTiCs=</Seed><PgenCounter>Asw=</PgenCounter></DSAKeyValue></KeyValue>"; value += "<KeyValue xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><RSAKeyValue><Modulus>9DC4XNdQJwMRnz5pP2a6U51MHCODRilaIoVXqUPhCUb0lJdGroeqVYT84ZyIVrcarzD7Tqs3aEOIa3rKox0N1bxQpZPqayVQeLAkjLLtzJW/ScRJx3uEDJdgT1JnM1FH0GZTinmEdCUXdLc7+Y/c/qqIkTfbwHbRZjW0bBJyExM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><RetrievalElement URI=\"http://www.go-mono.org/\" /><X509Data xmlns=\"http://www.w3.org/2000/09/xmldsig#\">"; value += "<X509Certificate>MIICHTCCAYYCARQwDQYJKoZIhvcNAQEEBQAwWDELMAkGA1UEBhMCQ0ExHzAdBgNVBAMTFktleXdpdG5lc3MgQ2FuYWRhIEluYy4xKDAmBgorBgEEASoCCwIBExhrZXl3aXRuZXNzQGtleXdpdG5lc3MuY2EwHhcNOTYwNTA3MDAwMDAwWhcNOTkwNTA3MDAwMDAwWjBYMQswCQYDVQQGEwJDQTEfMB0GA1UEAxMWS2V5d2l0bmVzcyBDYW5hZGEgSW5jLjEoMCYGCisGAQQBKgILAgETGGtleXdpdG5lc3NAa2V5d2l0bmVzcy5jYTCBnTANBgkqhkiG9w0BAQEFAAOBiwAwgYcCgYEAzSP6KuHtmPTp0JM+13qAAkzMwQKvXLYff/pXQm8w0SDFtSEHQCyphsLzZISuPYUu7YW9VLAYKO9q+BvnCxYfkyVPx/iOw7nKmIQOVdAv73h3xXIoX2C/GSvRcqK32D/glzRaAb0EnMh4Rc2TjRXydhARq7hbLp5S3YE+nGTIKZMCAQMwDQYJKoZIhvcNAQEEBQADgYEAMho1ur9DJ9a01Lh25eObTWzAhsl3NbprFi0TRkqwMlOhW1rpmeIMhogXTg3+gqxOR+/7/zms7jXI+lI3CkmtWa3iiqkcxl8f+G9zfs2gMegMvvVN2bKrihK2MHhoEXwN8UlNo/2y6f8d8JH6VIX/M5Dowb+km6RiRr1hElmYQYk=</X509Certificate></X509Data></KeyInfo>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(value); info.LoadXml(doc.DocumentElement); AssertCrypto.AssertXmlEquals("Import", value, (info.GetXml().OuterXml)); Assert.AreEqual(5, info.Count, "Import count"); }
protected IEnumerable <X509Certificate2> ReadKeyDescriptorElements(XmlNodeList keyDescriptorElements) { foreach (XmlElement keyDescriptorElement in keyDescriptorElements) { var keyInfoElement = keyDescriptorElement.SelectSingleNode($"*[local-name()='{Saml2MetadataConstants.Message.KeyInfo}']") as XmlElement; if (keyInfoElement != null) { var keyInfo = new KeyInfo(); keyInfo.LoadXml(keyInfoElement); var keyInfoEnumerator = keyInfo.GetEnumerator(); while (keyInfoEnumerator.MoveNext()) { var keyInfoX509Data = keyInfoEnumerator.Current as KeyInfoX509Data; if (keyInfoX509Data != null) { foreach (var certificate in keyInfoX509Data.Certificates) { if (certificate is X509Certificate2) { yield return(certificate as X509Certificate2); } } } } } } }
// Reads the X.509 certificates contained within an IdP or SP SSO descriptor private static void ReadX509Certificates(RoleDescriptorType roleDescriptor) { foreach (KeyDescriptor keyDescriptor in roleDescriptor.KeyDescriptors) { KeyInfo keyInfo = new KeyInfo(); keyInfo.LoadXml(keyDescriptor.KeyInfo); IEnumerator enumerator = keyInfo.GetEnumerator(typeof(KeyInfoX509Data)); while (enumerator.MoveNext()) { KeyInfoX509Data keyInfoX509Data = (KeyInfoX509Data)enumerator.Current; foreach (X509Certificate2 x509Certificate in keyInfoX509Data.Certificates) { Console.WriteLine("X509 certificate: " + x509Certificate.ToString()); } } foreach (XmlElement xmlElement in keyDescriptor.EncryptionMethods) { Console.WriteLine("Encryption method: " + KeyDescriptor.GetEncryptionMethodAlgorithm(xmlElement)); } } }
private IEnumerable <X509Certificate2> ReadKeyDescriptorElements(XmlNodeList keyDescriptorElements) { foreach (XmlElement keyDescriptorElement in keyDescriptorElements) { var keyInfoElement = keyDescriptorElement.FirstChild as XmlElement; if (keyInfoElement != null) { var keyInfo = new KeyInfo(); keyInfo.LoadXml(keyInfoElement); var keyInfoEnumerator = keyInfo.GetEnumerator(); while (keyInfoEnumerator.MoveNext()) { var keyInfoX509Data = keyInfoEnumerator.Current as KeyInfoX509Data; if (keyInfoX509Data != null) { foreach (var certificate in keyInfoX509Data.Certificates) { if (certificate is X509Certificate2) { yield return(certificate as X509Certificate2); } } } } } } }
public string Sign(string xmlDocument, RSA rsaKey) { CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); var xml = new XmlDocument { PreserveWhitespace = true }; xml.LoadXml(xmlDocument); if (xml.DocumentElement == null) { throw new CryptographicException($"The xml you are trying to Sign is invalid. \n {xmlDocument}"); } var signedXml = new SignedXml(xml) { SigningKey = rsaKey }; //signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; var dataObject = new DataObject(Guid.NewGuid().ToString(), "", "", xml.DocumentElement); signedXml.AddObject(dataObject); var x509Data = new KeyInfoX509Data(); var x509Certificate2 = new X509Certificate2("NPPAutomationClient.pem"); if (x509Certificate2.SerialNumber == null) { throw new CryptographicException("The X509Certificate you are trying to use is invalid. The Serial number is null."); } var keyInfo = new KeyInfo(); var keyInfoX509Data = new KeyInfoX509Data(); keyInfoX509Data.AddIssuerSerial(x509Certificate2.Issuer, x509Certificate2.SerialNumber); keyInfoX509Data.AddCertificate(x509Certificate2); keyInfo.AddClause(keyInfoX509Data); keyInfo.LoadXml(x509Data.GetXml()); var reference = new Reference { Uri = $"#{dataObject.Id}", DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256" }; var env = new XmlDsigC14NTransform(); reference.AddTransform(env); signedXml.AddReference(reference); signedXml.ComputeSignature(); var xmlDigitalSignature = signedXml.GetXml(); //xml.DocumentElement?.AppendChild(xml.ImportNode(xmlDigitalSignature, true)); return(xml.ImportNode(xmlDigitalSignature, true).OuterXml); }
private void CreateAndEmbedEncryptedKey(SymmetricAlgorithm symmetricAlgorithm, string tokenId, XmlElement securityElement, string dataId, string keyId) { var encryptedKey = CreatedEncryptedKey(symmetricAlgorithm, dataId, keyId); var keyInfoElement = CreateSecurityTokenReference(tokenId, null); var keyInfo = new KeyInfo(); keyInfo.LoadXml(keyInfoElement); encryptedKey.KeyInfo = keyInfo; var encryptedKeyElement = Document.ImportNode(encryptedKey.GetXml(), true); securityElement.AppendChild(encryptedKeyElement); }
/// <summary> /// Carga un elemento <code>ds:Signature</code> /// </summary> public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException("value"); } if ((value.LocalName == XmlSignatureConstants.ElementNames.Signature) && (value.NamespaceURI == XmlSignatureConstants.NamespaceURI)) { id = GetAttribute(value, XmlSignatureConstants.AttributeNames.Id); XmlNodeList xnl = value.GetElementsByTagName(XmlSignatureConstants.ElementNames.SignedInfo, XmlSignatureConstants.NamespaceURI); if ((xnl != null) && (xnl.Count == 1)) { info = new SignedInfo(); info.LoadXml((XmlElement)xnl[0]); } xnl = value.GetElementsByTagName(XmlSignatureConstants.ElementNames.SignatureValue, XmlSignatureConstants.NamespaceURI); if ((xnl != null) && (xnl.Count == 1)) { signature = Convert.FromBase64String(xnl[0].InnerText); } xnl = value.GetElementsByTagName(XmlSignatureConstants.ElementNames.KeyInfo, XmlSignatureConstants.NamespaceURI); if ((xnl != null) && (xnl.Count == 1)) { key = new KeyInfo(); key.LoadXml((XmlElement)xnl[0]); } xnl = value.GetElementsByTagName(XmlSignatureConstants.ElementNames.Object, XmlSignatureConstants.NamespaceURI); if ((xnl != null) && (xnl.Count > 0)) { foreach (XmlNode xn in xnl) { DataObject obj = new DataObject(); obj.LoadXml((XmlElement)xn); AddObject(obj); } } } if (info == null) { throw new CryptographicException("SignedInfo"); } if (signature == null) { throw new CryptographicException("SignatureValue"); } }
private static KeyInfo GetKeyInfoWithSecurityToken(string reference, Dictionary <string, XNamespace> namespaces) { var infoXml = new XElement("KeyInfo", new XElement(namespaces["wsse"] + "SecurityTokenReference", new XElement(namespaces["wsse"] + "Reference", new XAttribute("URI", $"#{reference}"), new XAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3")))); var document = GetXmlDocument(infoXml.ToString()); var keyInfo = new KeyInfo(); keyInfo.LoadXml(document.DocumentElement); return(keyInfo); }
protected override void StartPrimarySignatureCore(SecurityToken token, SecurityKeyIdentifier keyIdentifier, MessagePartSpecification signatureParts, bool generateTargettableSignature) { SecurityAlgorithmSuite suite = AlgorithmSuite; string canonicalizationAlgorithm = suite.DefaultCanonicalizationAlgorithm; if (canonicalizationAlgorithm != SecurityAlgorithms.ExclusiveC14n) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new MessageSecurityException(SR.Format(SR.UnsupportedCanonicalizationAlgorithm, suite.DefaultCanonicalizationAlgorithm))); } string signatureAlgorithm; XmlDictionaryString signatureAlgorithmDictionaryString; SecurityKey signatureKey; suite.GetSignatureAlgorithmAndKey(token, out signatureAlgorithm, out signatureKey, out signatureAlgorithmDictionaryString); AsymmetricAlgorithm asymmetricAlgorithm = null; GetSigningAlgorithm(signatureKey, signatureAlgorithm, out _signingKey, out asymmetricAlgorithm); _signedXml = new SignedXml(); _signedXml.SignedInfo.CanonicalizationMethod = canonicalizationAlgorithm; _signedXml.SignedInfo.SignatureMethod = signatureAlgorithm; _signedXml.SigningKey = asymmetricAlgorithm; if (keyIdentifier != null) { var stream = new MemoryStream(); using (var xmlWriter = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false)) { StandardsManager.SecurityTokenSerializer.WriteKeyIdentifier(xmlWriter, keyIdentifier); } stream.Position = 0; XmlDocument doc = new XmlDocument(); doc.Load(stream); var keyInfo = new KeyInfo(); keyInfo.LoadXml(doc.DocumentElement); _signedXml.KeyInfo = keyInfo; } if (generateTargettableSignature) { _signedXml.Signature.Id = GenerateId(); } _effectiveSignatureParts = signatureParts; }
public void ImportDSAKeyValue() { string p = "6zJxhRqpk5yQ7sjFSr6mPepyVwpTAXSmw1oh+5Cn/z1DjFSpW6rC6sTOkE3CMNwWOwIzrpVS3bWep7wo9CaBrOPIIVe+E4sqpPeyM2wr10mQThHEsCQAjnxBhJJindf9amaBhi6sOtVNnyETFWV6yKDptZEm9c3xdl4L7ogEbX8="; string q = "/0LHTzCnnmTZ0j7f4maA7NXrz60="; string g = "ZZefq7boKsU1pcKfRSOmsCo9QrV9N3j9aw2IP07PUoHS175vYPOBFduZIZXNmrnPEyTYpo3DaLUlTK9jsHh7TfIea4p4WC2sGF+2BgVXpioSGVFqbnZ29wIe3B6vWZtN1vSiapd9dgFklh3k65af1u3r2r9QpS2pH0BMBwCmvk8="; string y = "zWjWuf+4sK3p5BPpEcY8eYqcJcInFI+68HcTNjSi+0WqP+oKoQux+esVf1CfAWHcHxUFaZCWhUeqKxCN4bRUY95XZAwrMVqGFQtV3UMCzsJOYvzMtAVtOjD1Cl6d1b1i186zCkaodskgX+O0VcS/fPn+QAjIsIXWrFAuDmKfGVw="; string seed = "9/Y5blrHfG7EpAYQqkmgvaDzqKo="; string pgenCounter = "BAQ="; string dsaKeyXml = $@"<KeyInfo xmlns=""http://www.w3.org/2000/09/xmldsig#""><KeyValue><DSAKeyValue><P>{p}</P><Q>{q}</Q><G>{g}</G><Y>{y}</Y><Seed>{seed}</Seed><PgenCounter>{pgenCounter}</PgenCounter></DSAKeyValue></KeyValue></KeyInfo>"; var expected = new Dictionary <string, string>() { { "P", p }, { "Q", q }, { "G", g }, { "Y", y } }; XmlDocument doc = new XmlDocument(); doc.LoadXml(dsaKeyXml); KeyInfo info = new KeyInfo(); info.LoadXml(doc.DocumentElement); XmlElement el = info.GetXml(); foreach (var kv in expected) { XmlNode node = el.SelectSingleNode($"//*[local-name()='DSAKeyValue']/*[local-name()='{kv.Key}']"); Assert.NotNull(node); Assert.Equal(kv.Value, node.InnerText); } // Either both null or both have correct values XmlNode seedNode = el.SelectSingleNode($"//*[local-name()='DSAKeyValue']/*[local-name()='Seed']"); XmlNode counterNode = el.SelectSingleNode($"//*[local-name()='DSAKeyValue']/*[local-name()='PgenCounter']"); Assert.Equal(seedNode != null, counterNode != null); if (seedNode != null) { Assert.Equal(seed, seedNode.InnerText); Assert.Equal(pgenCounter, counterNode.InnerText); } }
public static KeyInfo GetKeyInfo(XmlElement xmlElement) { try { XmlElement keyInfoElement = XmlSignature.GetKeyInfoElement(xmlElement); if (keyInfoElement == null) { return((KeyInfo)null); } KeyInfo keyInfo = new KeyInfo(); keyInfo.LoadXml(keyInfoElement); return(keyInfo); } catch (Exception ex) { throw new SamlSignatureException("Failed to extract key info from XML.", ex); } }
private void SetKeyInfo(SignedXml signedXml, SecurityKeyIdentifier identifier) { if (identifier != null) { var stream = new MemoryStream(); using (var xmlWriter = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false)) { StandardsManager.SecurityTokenSerializer.WriteKeyIdentifier(xmlWriter, identifier); } stream.Position = 0; XmlDocument doc = new XmlDocument(); doc.Load(stream); var keyInfo = new KeyInfo(); keyInfo.LoadXml(doc.DocumentElement); signedXml.KeyInfo = keyInfo; } }
public void LoadXml(XmlElement value) { // Make sure we don't get passed null if (value == null) { throw new ArgumentNullException(nameof(value)); } // Signature XmlElement signatureElement = value; if (!signatureElement.LocalName.Equals("Signature")) { throw new CryptographicException("Hej1", "Signature"); } // Id attribute -- optional _id = Utils.GetAttribute(signatureElement, "Id", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(signatureElement, "Id")) { throw new CryptographicException("Hej2", "Signature"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); int expectedChildNodes = 0; // SignedInfo XmlNodeList signedInfoNodes = signatureElement.SelectNodes("ds:SignedInfo", nsm); if (signedInfoNodes == null || signedInfoNodes.Count == 0 || signedInfoNodes.Count > 1) { throw new CryptographicException("Hej3", "SignedInfo"); } XmlElement signedInfoElement = signedInfoNodes[0] as XmlElement; expectedChildNodes += signedInfoNodes.Count; // SignatureValue XmlNodeList signatureValueNodes = signatureElement.SelectNodes("ds:SignatureValue", nsm); if (signatureValueNodes == null || signatureValueNodes.Count == 0 || signatureValueNodes.Count > 1) { throw new CryptographicException("Hej4", "SignatureValue"); } XmlElement signatureValueElement = signatureValueNodes[0] as XmlElement; expectedChildNodes += signatureValueNodes.Count; _signatureValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(signatureValueElement.InnerText)); _signatureValueId = Utils.GetAttribute(signatureValueElement, "Id", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(signatureValueElement, "Id")) { throw new CryptographicException("Hej5", "SignatureValue"); } // KeyInfo - optional single element XmlNodeList keyInfoNodes = signatureElement.SelectNodes("ds:KeyInfo", nsm); _keyInfo = new KeyInfo(); if (keyInfoNodes != null) { if (keyInfoNodes.Count > 1) { throw new CryptographicException("Hej6", "KeyInfo"); } foreach (XmlNode node in keyInfoNodes) { XmlElement keyInfoElement = node as XmlElement; if (keyInfoElement != null) { _keyInfo.LoadXml(keyInfoElement); } } expectedChildNodes += keyInfoNodes.Count; } // Object - zero or more elements allowed XmlNodeList objectNodes = signatureElement.SelectNodes("ds:Object", nsm); _embeddedObjects.Clear(); if (objectNodes != null) { foreach (XmlNode node in objectNodes) { XmlElement objectElement = node as XmlElement; if (objectElement != null) { DataObject dataObj = new DataObject(); dataObj.LoadXml(objectElement); _embeddedObjects.Add(dataObj); } } expectedChildNodes += objectNodes.Count; } // Select all elements that have Id attributes /*XmlNodeList nodeList = signatureElement.SelectNodes("//*[@Id]", nsm); * if (nodeList != null) * { * foreach (XmlNode node in nodeList) * { * _referencedItems.Add(node); * } * }*/ // Verify that there aren't any extra nodes that aren't allowed if (signatureElement.SelectNodes("*").Count != expectedChildNodes) { throw new CryptographicException("Hej7", "Signature"); } }
public void ImportKeyNode() { string keyName = "Mono::"; string dsaP = "rjxsMU368YOCTQejWkiuO9e/vUVwkLtq1jKiU3TtJ53hBJqjFRuTa228vZe+BH2su9RPn/vYFWfQDv6zgBYe3eNdu4Afw+Ny0FatX6dl3E77Ra6Tsd3MmLXBiGSQ1mMNd5G2XQGpbt9zsGlUaexXekeMLxIufgfZLwYp67M+2WM="; string dsaQ = "tf0K9rMyvUrU4cIkwbCrDRhQAJk="; string dsaG = "S8Z+1pGCed00w6DtVcqZLKjfqlCJ7JsugEFIgSy/Vxtu9YGCMclV4ijGEbPo/jU8YOSMuD7E9M7UaopMRcmKQjoKZzoJjkgVFP48Ohxl1f08lERnButsxanx3+OstFwUGQ8XNaGg3KrIoZt1FUnfxN3RHHTvVhjzNSHxMGULGaU="; string dsaY = "LnrxxRGLYeV2XLtK3SYz8RQHlHFZYrtznDZyMotuRfO5uC5YODhSFyLXvb1qB3WeGtF4h3Eo4KzHgMgfN2ZMlffxFRhJgTtH3ctbL8lfQoDkjeiPPnYGhspdJxr0tyZmiy0gkjJG3vwHYrLnvZWx9Wm/unqiOlGBPNuxJ+hOeP8="; string dsaJ = "9RhE5TycDtdEIXxS3HfxFyXYgpy81zY5lVjwD6E9JP37MWEi80BlX6ab1YPm6xYSEoqReMPP9RgGiW6DuACpgI7+8vgCr4i/7VhzModJAA56PwvTu6UMt9xxKU/fT672v8ucREkMWoc7lEey"; string dsaSeed = "HxW3N4RHWVgqDQKuGg7iJTUTiCs="; string dsaPgenCounter = "Asw="; string rsaModulus = "9DC4XNdQJwMRnz5pP2a6U51MHCODRilaIoVXqUPhCUb0lJdGroeqVYT84ZyIVrcarzD7Tqs3aEOIa3rKox0N1bxQpZPqayVQeLAkjLLtzJW/ScRJx3uEDJdgT1JnM1FH0GZTinmEdCUXdLc7+Y/c/qqIkTfbwHbRZjW0bBJyExM="; string rsaExponent = "AQAB"; string x509cert = "MIICHTCCAYYCARQwDQYJKoZIhvcNAQEEBQAwWDELMAkGA1UEBhMCQ0ExHzAdBgNVBAMTFktleXdpdG5lc3MgQ2FuYWRhIEluYy4xKDAmBgorBgEEASoCCwIBExhrZXl3aXRuZXNzQGtleXdpdG5lc3MuY2EwHhcNOTYwNTA3MDAwMDAwWhcNOTkwNTA3MDAwMDAwWjBYMQswCQYDVQQGEwJDQTEfMB0GA1UEAxMWS2V5d2l0bmVzcyBDYW5hZGEgSW5jLjEoMCYGCisGAQQBKgILAgETGGtleXdpdG5lc3NAa2V5d2l0bmVzcy5jYTCBnTANBgkqhkiG9w0BAQEFAAOBiwAwgYcCgYEAzSP6KuHtmPTp0JM+13qAAkzMwQKvXLYff/pXQm8w0SDFtSEHQCyphsLzZISuPYUu7YW9VLAYKO9q+BvnCxYfkyVPx/iOw7nKmIQOVdAv73h3xXIoX2C/GSvRcqK32D/glzRaAb0EnMh4Rc2TjRXydhARq7hbLp5S3YE+nGTIKZMCAQMwDQYJKoZIhvcNAQEEBQADgYEAMho1ur9DJ9a01Lh25eObTWzAhsl3NbprFi0TRkqwMlOhW1rpmeIMhogXTg3+gqxOR+/7/zms7jXI+lI3CkmtWa3iiqkcxl8f+G9zfs2gMegMvvVN2bKrihK2MHhoEXwN8UlNo/2y6f8d8JH6VIX/M5Dowb+km6RiRr1hElmYQYk="; string retrievalElementUri = @"http://www.go-mono.org/"; string value = $@"<KeyInfo xmlns=""http://www.w3.org/2000/09/xmldsig#""> <KeyName>{keyName}</KeyName> <KeyValue xmlns=""http://www.w3.org/2000/09/xmldsig#""> <DSAKeyValue> <P>{dsaP}</P> <Q>{dsaQ}</Q> <G>{dsaG}</G> <Y>{dsaY}</Y> <J>{dsaJ}</J> <Seed>{dsaSeed}</Seed> <PgenCounter>{dsaPgenCounter}</PgenCounter> </DSAKeyValue> </KeyValue> <KeyValue xmlns=""http://www.w3.org/2000/09/xmldsig#""> <RSAKeyValue> <Modulus>{rsaModulus}</Modulus> <Exponent>{rsaExponent}</Exponent> </RSAKeyValue> </KeyValue> <RetrievalElement URI=""{retrievalElementUri}"" /> <X509Data xmlns=""http://www.w3.org/2000/09/xmldsig#""> <X509Certificate>{x509cert}</X509Certificate> </X509Data> </KeyInfo>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(value); info.LoadXml(doc.DocumentElement); Assert.Equal(5, info.Count); int i = 0; int pathsCovered = 0; foreach (var clause in info) { i++; if (clause is KeyInfoName) { pathsCovered |= 1 << 0; var name = clause as KeyInfoName; Assert.Equal(keyName, name.Value); } else if (clause is DSAKeyValue) { pathsCovered |= 1 << 1; var dsaKV = clause as DSAKeyValue; DSA dsaKey = dsaKV.Key; DSAParameters dsaParams = dsaKey.ExportParameters(false); Assert.Equal(Convert.FromBase64String(dsaP), dsaParams.P); Assert.Equal(Convert.FromBase64String(dsaQ), dsaParams.Q); Assert.Equal(Convert.FromBase64String(dsaG), dsaParams.G); Assert.Equal(Convert.FromBase64String(dsaY), dsaParams.Y); // J is an optimization it should either be null or correct value if (dsaParams.J != null) { Assert.Equal(Convert.FromBase64String(dsaJ), dsaParams.J); } // Seed and Counter are not guaranteed to roundtrip // they should either both be non-null or both null if (dsaParams.Seed != null) { Assert.Equal(Convert.FromBase64String(dsaSeed), dsaParams.Seed); byte[] counter = Convert.FromBase64String(dsaPgenCounter); Assert.InRange(counter.Length, 1, 4); int counterVal = 0; for (int j = 0; j < counter.Length; j++) { counterVal <<= 8; counterVal |= counter[j]; } Assert.Equal(counterVal, dsaParams.Counter); } else { Assert.Null(dsaParams.Seed); Assert.Equal(default(int), dsaParams.Counter); } } else if (clause is RSAKeyValue) { pathsCovered |= 1 << 2; var rsaKV = clause as RSAKeyValue; RSA rsaKey = rsaKV.Key; RSAParameters rsaParameters = rsaKey.ExportParameters(false); Assert.Equal(Convert.FromBase64String(rsaModulus), rsaParameters.Modulus); Assert.Equal(Convert.FromBase64String(rsaExponent), rsaParameters.Exponent); } else if (clause is KeyInfoNode) { pathsCovered |= 1 << 3; var keyInfo = clause as KeyInfoNode; XmlElement keyInfoEl = keyInfo.GetXml(); Assert.Equal("RetrievalElement", keyInfoEl.LocalName); Assert.Equal("http://www.w3.org/2000/09/xmldsig#", keyInfoEl.NamespaceURI); Assert.Equal(1, keyInfoEl.Attributes.Count); Assert.Equal("URI", keyInfoEl.Attributes[0].Name); Assert.Equal(retrievalElementUri, keyInfoEl.GetAttribute("URI")); } else if (clause is KeyInfoX509Data) { pathsCovered |= 1 << 4; var x509data = clause as KeyInfoX509Data; Assert.Equal(1, x509data.Certificates.Count); X509Certificate cert = x509data.Certificates[0] as X509Certificate; Assert.NotNull(cert); Assert.Equal(Convert.FromBase64String(x509cert), cert.GetRawCertData()); } else { Assert.True(false, $"Unexpected clause type: {clause.GetType().FullName}"); } } // 0x1f = b11111, number of ones = 5 Assert.Equal(pathsCovered, 0x1f); Assert.Equal(5, i); }
public static string SignXmlFile(string xml, RSA Key) { // Create a new XML document. var doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; using (var textReader = new StringReader(xml)) { doc.Load(new XmlTextReader(textReader)); } // Create a SignedXml object. var signedXml = new SignedXmlWithId(doc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Specify a canonicalization method. signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; // Set the InclusiveNamespacesPrefixList property. var canMethod = (XmlDsigExcC14NTransform)signedXml.SignedInfo.CanonicalizationMethodObject; var ref1 = new Reference("#Body52be6364-045f-1550-625d-b20b0390691e"); var ref2 = new Reference("#Timestamp5257ab43-882c-4937-3835-6763e9a2d700"); // Add an enveloped transformation to the reference. var env = new XmlDsigEnvelopedSignatureTransform(); ref1.AddTransform(canMethod); ref2.AddTransform(canMethod); // Add the reference to the SignedXml object. signedXml.AddReference(ref1); signedXml.AddReference(ref2); string keyInfoStr = "<KeyInfo><wsse:SecurityTokenReference xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"><wsse:Reference URI=\"#holderOfKeyCertificate\" ValueType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3\"/></wsse:SecurityTokenReference></KeyInfo>"; var xd = new XmlDocument(); xd.LoadXml(keyInfoStr); var ki = new KeyInfo(); ki.LoadXml(xd.DocumentElement); signedXml.KeyInfo = ki; // Compute the signature. //signedXml.ComputeSignature(KeyedHashAlgorithm.Create("HMACSHA256")); signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); xmlDigitalSignature.SetAttribute("Id", "holderOfKeyProofSignature"); var sb = new StringBuilder(); using (var sw = new StringWriter(sb)) { using (var writer = new XmlTextWriter(sw)) { xmlDigitalSignature.WriteTo(writer); } } return(sb.ToString()); }
/// <summary> /// An example on how to decrypt an encrypted assertion. /// </summary> /// <param name="file">The file.</param> public static void DecryptAssertion(string file) { var doc = new XmlDocument(); doc.Load(file); var encryptedDataElement = GetElement(Schema.XEnc.EncryptedData.ElementName, Saml20Constants.Xenc, doc); var encryptedData = new EncryptedData(); encryptedData.LoadXml(encryptedDataElement); var nodelist = doc.GetElementsByTagName(Schema.XmlDSig.KeyInfo.ElementName, Saml20Constants.Xmldsig); Assert.True(nodelist.Count > 0); var key = new KeyInfo(); key.LoadXml((XmlElement)nodelist[0]); // Review: Is it possible to figure out which certificate to load based on the Token? /* * Comment: * It would be possible to provide a key/certificate identifier in the EncryptedKey element, which contains the "recipient" attribute. * The implementation (Safewhere.Tokens.Saml20.Saml20EncryptedAssertion) currently just expects an appropriate asymmetric key to be provided, * and is not not concerned about its origin. * If the need arises, we can easily extend the Saml20EncryptedAssertion class with a property that allows extraction key info, eg. the "recipient" * attribute. */ var cert = Certificates.InMemoryResourceUtility.GetInMemoryCertificate("sts_dev_certificate.pfx", "test1234"); // ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.NETDEVFX.v20.en/CPref18/html/T_System_Security_Cryptography_Xml_KeyInfoClause_DerivedTypes.htm // Look through the list of KeyInfo elements to find the encrypted key. SymmetricAlgorithm symmetricKey = null; foreach (KeyInfoClause keyInfoClause in key) { if (keyInfoClause is KeyInfoEncryptedKey) { var keyInfoEncryptedKey = (KeyInfoEncryptedKey)keyInfoClause; var encryptedKey = keyInfoEncryptedKey.EncryptedKey; symmetricKey = new RijndaelManaged { Key = EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (RSA)cert.PrivateKey, false) }; } } // Explode if we didn't manage to find a viable key. Assert.NotNull(symmetricKey); var encryptedXml = new EncryptedXml(); var plaintext = encryptedXml.DecryptData(encryptedData, symmetricKey); var assertion = new XmlDocument(); assertion.Load(new StringReader(System.Text.Encoding.UTF8.GetString(plaintext))); // A very simple test to ensure that there is indeed an assertion in the plaintext. Assert.Equal(Assertion.ElementName, assertion.DocumentElement.LocalName); Assert.Equal(Saml20Constants.Assertion, assertion.DocumentElement.NamespaceURI); // At this point, assertion will contain a decrypted assertion. }