User Tools

Site Tools


br-236-api-csharp


API para aplicações C# .NET


// ========================================================================================
//
//   FOLLOWZUP PROJECT
//
// ========================================================================================
//
//   Copyright (C) 2016 Followzup.com
//
//   This program is free software: you can redistribute it and/or modify it under
//   the terms of the GNU General Public License as published by the Free Software
//   Foundation, either version 3 of the License, or any later version.
//
//   This program is distributed in the hope that it will be useful, but WITHOUT 
//   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
//   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program.  If not, see <http://www.gnu.org/licenses/>
//
// ========================================================================================

// ========================================
// Contributor: Marcelo Santos
// E-mail:      msantos2007 at yahoo.com.br
// ========================================

using System;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

using System.IO;

//Requires RestSharp: https://www.nuget.org/packages/RestSharp/
using RestSharp;

//Requires Bouncy Castle - https://www.nuget.org/packages/BouncyCastle/
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.OpenSsl;

namespace FollowZup.Services
{
    public class fzup_param
    {
        public fzup_param()
        {
            this.FZUP_COMMAND = "";
            this.FZUP_HOURS = 0;
            this.FZUP_LASTSEQ = 0;
            this.FZUP_MSGTEXT = "";
            this.FZUP_MSGURL = "";
            this.FZUP_SUBSCODE = "";
            this.FZUP_USER = "";
        }

        public string FZUP_COMMAND { get; set; }
        public int? FZUP_LASTSEQ { get; set; }
        public string FZUP_USER { get; set; }
        public string FZUP_SUBSCODE { get; set; }
        public int? FZUP_HOURS { get; set; }
        public string FZUP_MSGTEXT { get; set; }
        public string FZUP_MSGURL { get; set; }
    }

    public class fzup_result
    {
        public string fzup_retcode { get; set; }
        public int fzup_lastseq { get; set; }
        public string fzup_response { get; set; }
    }

    public class fzup_#idchannel#
    {
        public string fzup_channel = "#idchannel#";
        public string fzup_pubkey = "";
        public string fzup_pubkey64 = "#pubkey64#";
        public int fzup_lastseq = 0;

        public fzup_#idchannel#()
        {
            byte[] data = Convert.FromBase64String(fzup_pubkey64);
            this.fzup_pubkey = Encoding.UTF8.GetString(data);
        }

        public string decrypt(string fzup_encrypt64)
        {
            //Remember to enable CORS for http://www.followzup.com
            string result = "";
            try
            {
                result = RsaDecryptWithPublic(fzup_encrypt64, this.fzup_pubkey);
            }
            catch
            {
                try
                {
                    result = RsaDecryptWithPublic(System.Uri.UnescapeDataString(fzup_encrypt64), this.fzup_pubkey);
                }
                catch
                {
                    result = "";
                }
            }

            return result;
        }

        public fzup_result submit(fzup_param mensagem)
        {

            fzup_result result = new fzup_result();

            int seq = 0;
            mensagem.FZUP_LASTSEQ = mensagem.FZUP_LASTSEQ ?? seq;

            int hrs = 0;
            mensagem.FZUP_HOURS = mensagem.FZUP_HOURS ?? hrs; 

            byte[] b_FZUP_MSGTEXT = Encoding.UTF8.GetBytes(mensagem.FZUP_MSGTEXT);
            byte[] b_FZUP_MSGURL = Encoding.UTF8.GetBytes(mensagem.FZUP_MSGURL);
            mensagem.FZUP_MSGTEXT = Convert.ToBase64String(b_FZUP_MSGTEXT);
            mensagem.FZUP_MSGURL = Convert.ToBase64String(b_FZUP_MSGURL);

            string xml = "";
            string cmd = mensagem.FZUP_COMMAND;

            if (cmd == "chck")
            {
                xml = "";
                xml += "<usr>" + mensagem.FZUP_USER + "</usr>";
                xml += "<sub>" + mensagem.FZUP_SUBSCODE + "</sub>";
            }
            else
            {
                if (cmd == "smsg")
                {
                    xml = "";
                    xml += "<usr>" + mensagem.FZUP_USER + "</usr>";
                    xml += "<hrs>" + mensagem.FZUP_HOURS + "</hrs>";
                    xml += "<msg>" + mensagem.FZUP_MSGTEXT + "</msg>";
                    xml += "<url>" + mensagem.FZUP_MSGURL + "</url>";
                }
                else
                {
                    result.fzup_retcode = "6103";
                    result.fzup_lastseq = this.fzup_lastseq;
                    result.fzup_response = @"<?xml version=""1.0"" encoding=""utf-8""?><followzup></followzup>";

                    return result;
                };
            }

            if (mensagem.FZUP_LASTSEQ > 0) fzup_lastseq = (int)mensagem.FZUP_LASTSEQ;

            string fzup_RetCode = "";
            string fzup_frame1 = "";
            byte[] fzup_frame2;
            string fzup_frame3 = "";
            byte[] fzup_key1;
            byte[] fzup_key2;
            string fzup_key3 = null;

            string fzup_retframe4 = "";


            do
            {
                this.fzup_lastseq++;

                fzup_frame1 = "";
                fzup_frame1 += @"<?xml version=""1.0"" encoding=""utf-8""?>";
                fzup_frame1 += "<followzup>";
                fzup_frame1 += "<com>" + mensagem.FZUP_COMMAND + "</com>";
                fzup_frame1 += "<seq>" + this.fzup_lastseq + "</seq>";
                fzup_frame1 += xml;
                fzup_frame1 += "</followzup>";

                //AES - Encryption
                //Padding with spaces to complete 16 bytes block, because of "rijAlg.Padding = PaddingMode.None"
                //IV - Important: ASCII "null" char "0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
                byte[] n_plain = Encoding.UTF8.GetBytes(fzup_frame1);
                int n_length = n_plain.Length;
                int p_length = n_length + (15 - ((n_length - 1) % 16));
                byte[] b_plain = Enumerable.Repeat((byte)0x20, p_length).ToArray();
                Array.Copy(n_plain, 0, b_plain, 0, n_length);

                fzup_frame1 = Encoding.UTF8.GetString(b_plain);

                RijndaelManaged rijAlg = new RijndaelManaged();

                rijAlg.BlockSize = 128;
                rijAlg.KeySize = 192;
                rijAlg.Mode = CipherMode.CBC;
                rijAlg.Padding = PaddingMode.None;
                rijAlg.GenerateKey();
                
                byte[] null_char_byte = Enumerable.Repeat((byte)0x00, 16).ToArray();
                string null_char_strg = Encoding.UTF8.GetString(null_char_byte);

                rijAlg.IV = null_char_byte;

                ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(fzup_frame1);
                        }
                        fzup_frame2 = msEncrypt.ToArray();
                    }
                }

                fzup_key1 = rijAlg.Key;

                //RSA - Encryption 
                string publicKey_noHeader = this.fzup_pubkey;
                publicKey_noHeader = publicKey_noHeader.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");

                RSACryptoServiceProvider RSAenc = DecodeX509PublicKey(Convert.FromBase64String(publicKey_noHeader));

                fzup_key2 = RSAenc.Encrypt(fzup_key1, false);
                fzup_key3 = Convert.ToBase64String(fzup_key2);
                fzup_frame3 = Convert.ToBase64String(fzup_frame2);
 
                //RestSharp
                IRestResponse response = null;
                var client = new RestClient("http://www.followzup.com");
                var request = new RestRequest("/wschannel", Method.POST);

                client.UserAgent = "wschannel: " + this.fzup_channel;

                request.AddParameter("id", this.fzup_channel);
                request.AddParameter("key", fzup_key3);
                request.AddParameter("frame", fzup_frame3);
                response = client.Execute(request);
                System.Xml.XmlDocument responsexml = new System.Xml.XmlDocument();
                responsexml.LoadXml(response.Content.ToString());

                System.Xml.XmlNodeList xn = responsexml.SelectNodes("/followzup");
                fzup_RetCode = xn[0].SelectSingleNode("retcode").InnerText;
                string fzup_retframe1 = xn[0].SelectSingleNode("retframe").InnerText;
                string fzup_retframe2 = "";

                //AES - Decryption
                ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

                using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(fzup_retframe1)))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            fzup_retframe2 = srDecrypt.ReadToEnd();
                        }
                    }
                }

                if (fzup_RetCode == "6101")
                {
                    System.Xml.XmlDocument fzup_retframe3 = new System.Xml.XmlDocument();
                    fzup_retframe3.LoadXml(fzup_retframe2);

                    System.Xml.XmlNodeList xL = fzup_retframe3.SelectNodes("/followzup");

                    this.fzup_lastseq = Convert.ToInt32(xL[0].SelectSingleNode("seq").InnerText);
                }

                fzup_retframe4 = fzup_retframe2;

            } while (fzup_RetCode == "6101");

            result.fzup_retcode = fzup_RetCode;
            result.fzup_lastseq = this.fzup_lastseq;
            result.fzup_response = fzup_retframe4;

            return result;
        }
        
        public RSACryptoServiceProvider DecodeX509PublicKey(byte[] x509key)
        { 
            byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
            byte[] seq = new byte[15]; 
            MemoryStream mem = new MemoryStream(x509key);
            BinaryReader binr = new BinaryReader(mem);
            byte bt = 0;
            ushort twobytes = 0;

            try
            {
                twobytes = binr.ReadUInt16();
                if (twobytes == 0x8130)
                    binr.ReadByte();
                else if (twobytes == 0x8230)
                    binr.ReadInt16();
                else
                    return null;

                seq = binr.ReadBytes(15);
                if (!CompareBytearrays(seq, SeqOID))
                    return null;

                twobytes = binr.ReadUInt16();
                if (twobytes == 0x8103)
                    binr.ReadByte();
                else if (twobytes == 0x8203)
                    binr.ReadInt16();
                else
                    return null;

                bt = binr.ReadByte();
                if (bt != 0x00)
                    return null;

                twobytes = binr.ReadUInt16();
                if (twobytes == 0x8130)
                    binr.ReadByte();
                else if (twobytes == 0x8230)
                    binr.ReadInt16();
                else
                    return null;

                twobytes = binr.ReadUInt16();
                byte lowbyte = 0x00;
                byte highbyte = 0x00;

                if (twobytes == 0x8102)
                    lowbyte = binr.ReadByte();
                else if (twobytes == 0x8202)
                {
                    highbyte = binr.ReadByte();
                    lowbyte = binr.ReadByte();
                }
                else
                    return null;
                byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
                int modsize = BitConverter.ToInt32(modint, 0);

                byte firstbyte = binr.ReadByte();
                binr.BaseStream.Seek(-1, SeekOrigin.Current);

                if (firstbyte == 0x00)
                {   
                    binr.ReadByte();
                    modsize -= 1;
                }

                byte[] modulus = binr.ReadBytes(modsize);

                if (binr.ReadByte() != 0x02)
                    return null;
                int expbytes = (int)binr.ReadByte();
                byte[] exponent = binr.ReadBytes(expbytes);

                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                RSAParameters RSAKeyInfo = new RSAParameters();
                RSAKeyInfo.Modulus = modulus;
                RSAKeyInfo.Exponent = exponent;
                RSA.ImportParameters(RSAKeyInfo);
                return RSA;
            }
            catch (Exception)
            {
                return null;
            }

            finally
            {
                binr.Close();
            }
        }

        public bool CompareBytearrays(byte[] a, byte[] b)
        {
            if (a.Length != b.Length)
                return false;
            int i = 0;
            foreach (byte c in a)
            {
                if (c != b[i])
                    return false;
                i++;
            }
            return true;
        }

        public string RsaDecryptWithPublic(string base64Input, string publicKey)
        {
            //Bouncy Castle
            var bytesToDecrypt = Convert.FromBase64String(base64Input);

            var decryptEngine = new Pkcs1Encoding(new RsaEngine());

            using (var txtreader = new StringReader(publicKey))
            {
                var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject();

                decryptEngine.Init(false, keyParameter);
            }

            var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));

            return decrypted;
        }
    }
}


br-236-api-csharp.txt · Last modified: 2017/06/27 21:21 by admin

Page Tools