public byte [] Encrypt(byte [] plain) { //int iters = plain.Length / 8; int rem = plain.Length % 8; if (rem != 0) { throw new Exception("must be in 8 byte blocks"); } //just encrypt and throw away the last 8 bytes byte [] cipher = _tdcsp.EncryptValue(plain); byte [] cipherNoPad = new byte[cipher.Length - _tdcsp.IV.Length]; Array.Copy(cipher, 0, cipherNoPad, 0, cipherNoPad.Length); /* * byte [] cipher = new byte[plain.Length]; * for(int i=0; i<iters; i++) * { * int offset = i * 8; * byte [] plainBlock = new byte[8]; * Array.Copy(plain, offset, plainBlock, 0, 8); * byte [] cipherBlock = _tdcsp.EncryptValue(plainBlock); * Array.Copy(cipherBlock, 0, cipher, offset, 8); * } * return cipher; */ return(cipherNoPad); }
public static XmlDocument EncryptXml(XmlDocument plainDoc) { if (EncObj == null) { return(plainDoc); //nothing to encrypt } XmlElement envelope = plainDoc.DocumentElement; //add namespace //XmlAttribute xenc = xd.CreateAttribute(Pre.xmlns, Pre.xenc, Ns.xmlns); //xenc.Value = Ns.xenc; //envelope.Attributes.Append(xenc); XmlElement headerOrBody = (XmlElement)envelope.ChildNodes[0]; XmlElement header; XmlElement body; if (headerOrBody.LocalName == Elem.Body) { header = plainDoc.CreateElement(headerOrBody.Prefix, Elem.Header, headerOrBody.NamespaceURI); envelope.InsertBefore(header, headerOrBody); } header = (XmlElement)envelope.ChildNodes[0]; body = (XmlElement)envelope.ChildNodes[1]; XmlNodeList headers = header.ChildNodes; XmlElement security = null; foreach (XmlNode xn in headers) { if (xn.LocalName == Elem.Security) { security = (XmlElement)xn; } } if (security == null) { //used to work for SymmetricEncryptionV1 //if(EncObj.SecTokRef != null) //symmetric is older // security = plainDoc.CreateElement(Pre.wsse, Elem.Security, Ns.wsse0207); //else //newest security = plainDoc.CreateElement(Pre.wsse, Elem.Security, Ns.wsseLatest); XmlAttribute mustUnderstand = plainDoc.CreateAttribute(Pre.soap, Attrib.mustUnderstand, Ns.soap); mustUnderstand.Value = "1"; security.Attributes.Append(mustUnderstand); header.AppendChild(security); } XmlElement tokenElem = null; if (EncObj.UserTok != null) { XmlElement userTokElem = LameXpath.SelectSingleNode(security, Elem.UsernameToken); if (userTokElem == null) { EncObj.UserTok.WriteXml(plainDoc, security); } tokenElem = userTokElem; //secTokId = SigObj.UserTok.Id; //sigAlgVal = "http://www.w3.org/2000/09/xmldsig#hmac-sha1"; } /* * <wsse:Security soap:mustUnderstand="1"> * <wsse:BinarySecurityToken ValueType="wsse:X509v3" * EncodingType="wsse:Base64Binary" * xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" * wsu:Id="SecurityToken-b2adaba3-09f7-45a0-aa0d-0c4da15d0725"> * MIIBxDCCAW6...== * </wsse:BinarySecurityToken> * </wsse:Security> */ if (EncObj.BinSecTok != null) { XmlElement binSecTok = LameXpath.SelectSingleNode(security, Elem.BinarySecurityToken); if (binSecTok == null) { EncObj.BinSecTok.WriteXml(plainDoc, security); } tokenElem = binSecTok; } /* * <wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext"> * <xenc:ReferenceList xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> * <xenc:DataReference URI="#EncryptedContent-c163b16f-44c7-4eea-ac65-a6ce744e2651" /> * </xenc:ReferenceList> * </wsse:Security> */ if (EncObj.SecTokRef != null) // || EncObj.ClearPassword != null { //security.Attributes["xmlns"].Value = Ns.wsse0207; XmlElement referenceList = plainDoc.CreateElement(Pre.xenc, Elem.ReferenceList, Ns.xenc); XmlElement dataReference = plainDoc.CreateElement(Pre.xenc, Elem.DataReference, Ns.xenc); XmlAttribute uri = plainDoc.CreateAttribute(Attrib.URI); uri.Value = "#" + EncObj.Id; dataReference.Attributes.Append(uri); referenceList.AppendChild(dataReference); if (SignFirst == false) { security.AppendChild(referenceList); //just append } else { security.InsertAfter(referenceList, tokenElem); //after token } } /* * <wsse:Security soap:mustUnderstand="1"> * <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> * <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> * <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> * <wsse:SecurityTokenReference> * <wsse:KeyIdentifier ValueType="wsse:X509v3">gBfo0147lM6cKnTbbMSuMVvmFY4=</wsse:KeyIdentifier> * </wsse:SecurityTokenReference> * </KeyInfo> * <xenc:CipherData> * <xenc:CipherValue>CKc0qzMkc...==</xenc:CipherValue> * </xenc:CipherData> * <xenc:ReferenceList> * <xenc:DataReference URI="#EncryptedContent-702cd57e-c5ca-44c6-9bd8-b8639762b036" /> * </xenc:ReferenceList> * </xenc:EncryptedKey> * </wsse:Security> */ if (EncObj.EncKey != null) { XmlElement encKeyElem = plainDoc.CreateElement(Pre.xenc, Elem.EncryptedKey, Ns.xenc); XmlElement encMethElem = plainDoc.CreateElement(Pre.xenc, Elem.EncryptionMethod, Ns.xenc); XmlAttribute alg = plainDoc.CreateAttribute(Attrib.Algorithm); alg.Value = Alg.rsa15; encMethElem.Attributes.Append(alg); encKeyElem.AppendChild(encMethElem); XmlElement keyInfoElem = plainDoc.CreateElement(Pre.ds, Elem.KeyInfo, Ns.ds); XmlElement secTokRefElem = plainDoc.CreateElement(Pre.wsse, Elem.SecurityTokenReference, Ns.wsseLatest); XmlElement keyIdElem = plainDoc.CreateElement(Pre.wsse, Elem.KeyIdentifier, Ns.wsseLatest); XmlAttribute valueType = plainDoc.CreateAttribute(Attrib.ValueType); //valueType.Value = "wsse:X509v3"; valueType.Value = Misc.tokenProfX509 + "#X509SubjectKeyIdentifier"; keyIdElem.Attributes.Append(valueType); keyIdElem.InnerText = EncObj.KeyId; secTokRefElem.AppendChild(keyIdElem); keyInfoElem.AppendChild(secTokRefElem); encKeyElem.AppendChild(keyInfoElem); //encrypt key byte [] baSessKey = EncObj.SymmAlg.Key; byte [] baEncSessKey = EncObj.RSACSP.EncryptValue(baSessKey); XmlElement ciphDataElem = plainDoc.CreateElement(Pre.xenc, Elem.CipherData, Ns.xenc); XmlElement ciphValElem = plainDoc.CreateElement(Pre.xenc, Elem.CipherValue, Ns.xenc); ciphValElem.InnerText = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(baEncSessKey); ciphDataElem.AppendChild(ciphValElem); encKeyElem.AppendChild(ciphDataElem); XmlElement refListElem = plainDoc.CreateElement(Pre.xenc, Elem.ReferenceList, Ns.xenc); XmlElement dataRefElem = plainDoc.CreateElement(Pre.xenc, Elem.DataReference, Ns.xenc); XmlAttribute uri = plainDoc.CreateAttribute(Attrib.URI); uri.Value = "#" + EncObj.Id; dataRefElem.Attributes.Append(uri); refListElem.AppendChild(dataRefElem); encKeyElem.AppendChild(refListElem); //security.PrependChild(encKeyElem); if (SignFirst == false) { security.AppendChild(encKeyElem); //just append } else { security.InsertAfter(encKeyElem, tokenElem); //after token } } //SecurityContextToken - add here, or with Signature string secTokId = null; if (EncObj.securityContextToken != null) { XmlNode sctNode = LameXpath.SelectSingleNode(header, Elem.SecurityContextToken); if (sctNode == null) { //i need to import this node 1st sctNode = plainDoc.ImportNode(EncObj.securityContextToken, true); string dupeId = sctNode.Attributes[Attrib.Id, Ns.wsuLatest].Value; XmlElement dupeElem = LameXpath.SelectSingleNode(dupeId, security); if (dupeElem == null) { security.AppendChild(sctNode); } else { sctNode = LameXpath.SelectSingleNode(dupeId, security); } } //<wsse:SecurityContextToken wsu:Id=\"SecurityToken-feb27552-6eb5-4a27-a831-e1bdfca326e2\"> secTokId = sctNode.Attributes[Attrib.Id, Ns.wsuLatest].Value; //add ReferenceList too for SecureConversation //<xenc:ReferenceList xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> // <xenc:DataReference URI="#EncryptedContent-cb7efc1c-e4dd-4737-9214-aec967789d2d" /> //</xenc:ReferenceList> XmlElement referenceListElem = plainDoc.CreateElement(Pre.xenc, Elem.ReferenceList, Ns.xenc); //security.AppendChild(referenceListElem); XmlElement dataReferenceElem = plainDoc.CreateElement(Pre.xenc, Elem.DataReference, Ns.xenc); XmlAttribute uriAttrib = plainDoc.CreateAttribute(Attrib.URI); uriAttrib.Value = "#" + EncObj.Id; dataReferenceElem.Attributes.Append(uriAttrib); referenceListElem.AppendChild(dataReferenceElem); security.InsertAfter(referenceListElem, sctNode); if (EncObj.derKeyTok != null) { XmlNode idElem = LameXpath.SelectSingleNode(sctNode, Elem.Identifier); if (idElem != null) { EncObj.derKeyTok.secTokRef.Reference.URI = idElem.InnerText; } XmlElement derKeyTokElem = EncObj.derKeyTok.WriteXml(plainDoc, security, (XmlElement)sctNode); secTokId = EncObj.derKeyTok.id; EncObj.SymmAlg.Key = EncObj.derKeyTok.derKey; } } if (EncObj.UserTok != null) { int numBytes = EncObj.SymmAlg.Key.Length; byte [] derKey = P_SHA1.DeriveKey(EncObj.ClearPassword, XmlSigHandler.StrKeyLabel, EncObj.UserTok.Nonce.Text, EncObj.UserTok.Created, numBytes); EncObj.SymmAlg.Key = derKey; } //possibly add BinSecTok, but dont encrypt if (EncObj.SymmAlg == null) { return(plainDoc); } if (EncObj.RSACSP == null && EncObj.UserTok == null && EncObj.securityContextKey == null && EncObj.derKeyTok.derKey == null) { return(plainDoc); } XmlElement plainElement = LameXpath.SelectSingleNode(envelope, EncObj.TargetElement); if (plainElement == null) { throw new Exception("element not found to encrypt"); } byte [] baPlain; if (EncObj.Type == PlainTextType.Element) { baPlain = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetBytes(plainElement.OuterXml); } else if (EncObj.Type == PlainTextType.Content) { baPlain = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetBytes(plainElement.InnerXml); } else { throw new Exception("only support #Element and #Content"); } //diff algorithms SymmetricAlgorithm sa = EncObj.SymmAlg; sa.IV = OpenNETCF.Security.Cryptography.NativeMethods.Rand.GetRandomBytes(sa.IV.Length); byte [] baCipher = sa.EncryptValue(baPlain); byte [] baCipherIv = new byte[baCipher.Length + sa.IV.Length]; Array.Copy(sa.IV, 0, baCipherIv, 0, sa.IV.Length); Array.Copy(baCipher, 0, baCipherIv, sa.IV.Length, baCipher.Length); //byte [] baEncTest = Format.GetB64("JgiIRPjmEMW/QVXB6/KRICQrO5B9CSWo8pgqWoAA4TL2BFSkeuerfumauP6lneK8eRHz+iSG2Bcvu+4FXnYjRkQO4We7MdEL5C9HB9hFu7+GTnmTcL+aVh3Ue3bfrJq0"); //byte [] baTest = tCsp.DecryptValue(baEncTest); //string strEncText = Format.GetString(baTest); /* * <xenc:EncryptedData Id="EncryptedContent-c163b16f-44c7-4eea-ac65-a6ce744e2651" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> * <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /> * <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> * <KeyName>WSE Sample Symmetric Key</KeyName> //NORMAL * <wsse:SecurityTokenReference> //SecureConversation * <wsse:Reference URI="#SecurityToken-be84969f-41c7-4dff-95a4-7319a3122142" /> * </wsse:SecurityTokenReference> * </KeyInfo> * <xenc:CipherData> * <xenc:CipherValue>1+uBlSL/pxXyl2FdeT/EVM6TZgW9cv1AjwlJ9LZyKejet9TgjK37QoURZklglS9z+yGd5XooIDhtWPLaw3ApuhRCky6Y8eP1+3mT6v+t3o28idscfYOrkFmVaI25AwHK</xenc:CipherValue> * </xenc:CipherData> * </xenc:EncryptedData> */ XmlElement encryptedData = plainDoc.CreateElement(Pre.xenc, Elem.EncryptedData, Ns.xenc); XmlAttribute id = plainDoc.CreateAttribute(Attrib.Id); id.Value = EncObj.Id; encryptedData.Attributes.Append(id); XmlAttribute type = plainDoc.CreateAttribute(Attrib.Type); type.Value = Misc.plainTextTypeContent; //xeo.Type.ToString(); encryptedData.Attributes.Append(type); XmlElement encryptionMethod = plainDoc.CreateElement(Pre.xenc, Elem.EncryptionMethod, Ns.xenc); XmlAttribute algorithm = plainDoc.CreateAttribute(Attrib.Algorithm); if (EncObj.SymmAlg is TripleDES) { algorithm.Value = Alg.tripledesCbc; //xeo.AlgorithmEnum.ToString(); } else { algorithm.Value = Alg.aes128cbc; } encryptionMethod.Attributes.Append(algorithm); encryptedData.AppendChild(encryptionMethod); if ((EncObj.KeyName != null && EncObj.KeyName != String.Empty) || EncObj.securityContextToken != null || EncObj.ClearPassword != null) { XmlElement keyInfo = plainDoc.CreateElement(Pre.ds, Elem.KeyInfo, Ns.ds); if (EncObj.KeyName != null && EncObj.KeyName != String.Empty) { XmlElement keyName = plainDoc.CreateElement(Pre.ds, Elem.KeyName, Ns.ds); keyName.InnerText = EncObj.KeyName; keyInfo.AppendChild(keyName); } if (EncObj.securityContextToken != null || EncObj.ClearPassword != null) { XmlElement securityTokenReferenceElem = plainDoc.CreateElement(Pre.wsse, Elem.SecurityTokenReference, Ns.wsseLatest); keyInfo.AppendChild(securityTokenReferenceElem); XmlElement referenceElem = plainDoc.CreateElement(Pre.wsse, Elem.Reference, Ns.wsseLatest); securityTokenReferenceElem.AppendChild(referenceElem); if (EncObj.securityContextToken != null) { XmlAttribute uriAttrib = plainDoc.CreateAttribute(Attrib.URI); uriAttrib.Value = "#" + secTokId; referenceElem.Attributes.Append(uriAttrib); } if (EncObj.UserTok != null) { XmlAttribute uriAttrib = plainDoc.CreateAttribute(Attrib.URI); uriAttrib.Value = "#" + EncObj.UserTok.Id; referenceElem.Attributes.Append(uriAttrib); XmlAttribute valueTypeAttrib = plainDoc.CreateAttribute(Attrib.ValueType); valueTypeAttrib.Value = Misc.tokenProfUsername + "#UsernameToken"; referenceElem.Attributes.Append(valueTypeAttrib); } } encryptedData.AppendChild(keyInfo); } XmlElement cipherData = plainDoc.CreateElement(Pre.xenc, Elem.CipherData, Ns.xenc); XmlElement cipherValue = plainDoc.CreateElement(Pre.xenc, Elem.CipherValue, Ns.xenc); cipherValue.InnerText = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(baCipherIv); cipherData.AppendChild(cipherValue); encryptedData.AppendChild(cipherData); if (EncObj.Type == PlainTextType.Element) { plainElement.ParentNode.InnerXml = encryptedData.OuterXml; } else //content { plainElement.InnerXml = encryptedData.OuterXml; } SecConvObj = null; EncObj = null; return(plainDoc); }