コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }