移动云发短信(C#版)

一、根据 选择的协议(下图是客户截图给我的,故凑合着看吧)

下载对应的文档,http协议的下载上面那份,ws协议的下载下面那份,注意:如果协议不对,统统返回InvalidUsrOrPwd
 

 

二、写代码之前,建议先用PostMan试试发短信,随后再写代码。由于接口需要base64加密解密和md5的计算,这里推荐一个网站(http://tool.chinaz.com/tools/base64.aspx)全部搞定
假设

ecName:政企分公司测试

接口账号:demo0

接口密码:123qwe

接收短信的手机:13800138000

短信内容:移动改变生活。

签名:DWItALe3A
1、先试HTTP的,地址在HTTP的文档里有

得到md5结果后,组装这样一个json字符串(代码中肯定要拿json解析的类操作的)

{"ecName":"政企分公司测试", "apId":"demo0", "mobiles":"13800138000", "content":"移动改变生活。", "sign":"DWItALe3A", "addSerial":"", "mac":"7997ddb079db2155b517b21b2a812370"}

 得到Base64码后就可以发PostMan测试了,注意,Content-Type设置成application/json

 由于账号密码不对的,所以一定会返回InvalidUsrOrPwd

 

 2、再来试WS的,地址在WS的文档里有

 WS的不用Base64加密,md5的获取和上面一样,然后就可以组装xml代码发过去了,如下

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <sendSms xmlns="http://server.webservice.service.mgw.mascloud.umpay.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <arg0 xmlns=""><![CDATA[<?xml version="1.0" encoding="utf-8"?><WsSubmitReq><apId>demo0</apId><secretKey>123qwe</secretKey><ecName>政企分公司测试</ecName><mobiles><string>13800138000</string></mobiles><content>移动改变生活。</content><sign>DWItALe3A</sign><addSerial></addSerial><mac>7997ddb079db2155b517b21b2a812370</mac></WsSubmitReq>]]>
            </arg0>
        </sendSms>
    </s:Body>
</s:Envelope>

注意,Content-Type设置成text/xml

注意:<arg0>标签的内容不允许有任何空格或换行符(你们可以试下,反正我试了就会这样)

 

 

 正确的应该会返回这个,当然由于账号密码不对的,所以是InvalidUsrOrPwd

 

 

三、代码部分
新建一个.Net Core控制台就能运行了
1、Http协议的(注意:Newtonsoft.Json这个自行下载Nuget包,或者你用别的操作json也行)

using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        public static async Task Main()
        {
            var httpClient = new HttpClient();
            var secretKey = "123qwe"; //接口密码不用发过去
            var para = new MasCloudPara()
            {
                ecName = "政企分公司测试",
                apId = "demo0",
                mobiles = "13800138000",
                content = "移动改变生活。",
                sign = "DWItALe3A",
                addSerial = ""
            };

            try
            {
                para.mac = (para.ecName + para.apId + secretKey + para.mobiles + para.content + para.sign +
                            para.addSerial).GetMd5();
                var json = JsonConvert.SerializeObject(para);
                if (string.IsNullOrEmpty(json))
                {
                    return;
                }

                var content = json.EncodeBase64(Encoding.UTF8);
                var url = "http://112.35.1.155:1992/sms/norsubmit";
                var stringContent = new StringContent(content, Encoding.UTF8, "application/json");
                var response = await httpClient.PostAsync(url, stringContent);
                var responseStr = await response.Content.ReadAsStringAsync();
                var masCloudResponse = JsonConvert.DeserializeObject<MasCloudResponse>(responseStr);

                if (masCloudResponse.success)
                {
                    Console.WriteLine("发送成功");
                }
                else
                {
                    Console.WriteLine("发送失败" + masCloudResponse.rspcod);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            Console.ReadKey();
        }

        /// <summary>
        /// 请求参数
        /// </summary>
        public class MasCloudPara
        {
            /// <summary>
            /// 企业名称
            /// </summary>
            public string ecName { get; set; }
            /// <summary>
            /// 接口账号用户名
            /// </summary>
            public string apId { get; set; }
            /// <summary>
            /// 收信手机号码。英文逗号分隔,每批次限5000个号码
            /// </summary>
            public string mobiles { get; set; }
            /// <summary>
            /// 短信内容。如content中存在双引号,请务必使用转义符\在报文中进行转义(使用JSON转换工具转换会自动增加转义符),否则会导致服务端解析报文异常。
            /// </summary>
            public string content { get; set; }
            /// <summary>
            /// 签名编码。在云MAS平台『管理』→『接口管理』→『短信接入用户管理』获取。
            /// </summary>
            public string sign { get; set; }
            /// <summary>
            /// 扩展码。依据申请开户的服务代码匹配类型而定,如为精确匹配,此项填写空字符串("");如为模糊匹配,此项可填写空字符串或自定义的扩展码,注:服务代码加扩展码总长度不能超过20位
            /// </summary>
            public string addSerial { get; set; }
            /// <summary>
            /// 参数校验序列,生成方法:将ecName、apId、secretKey、mobiles、content、sign、addSerial按序拼接(无间隔符),通过MD5(32位小写)计算得出值。
            /// </summary>
            public string mac { get; set; }
        }

        /// <summary>
        /// 响应结果
        /// </summary>
        public class MasCloudResponse
        {
            /// <summary>
            /// 响应状态
            /// </summary>
            public string rspcod { get; set; }
            /// <summary>
            /// 消息批次号,由云MAS平台生成,用于关联短信发送请求与状态报告,注:若数据验证不通过,该参数值为空。
            /// </summary>
            public string mgsGroup { get; set; }
            /// <summary>
            /// 数据校验结果
            /// </summary>
            public bool success { get; set; }
        }
    }

    public static class Extend
    {
        /// <summary>
        /// Base64加密
        /// </summary>
        /// <param name="encode">加密采用的编码方式</param>
        /// <param name="source">待加密的明文</param>
        /// <returns>失败返回null</returns>
        public static string EncodeBase64(this string source, Encoding encode)
        {
            var bytes = encode.GetBytes(source);
            return Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// 计算MD5(32位小写)
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string GetMd5(this string source)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            var fromData = System.Text.Encoding.UTF8.GetBytes(source);
            var targetData = md5.ComputeHash(fromData);
            var byte2String = string.Empty;
            foreach (var data in targetData)
            {
                //这个是很常见的错误,你字节转换成字符串的时候要保证是2位宽度啊,某个字节为0转换成字符串的时候必须是00的,否则就会丢失位数啊。不仅是0,1~9也一样。
                //byte2String += targetData[i].ToString("x");//这个会丢失
                byte2String += data.ToString("x2");
            }

            return byte2String;
        }
    }
}
Http协议的

2、WS协议的(发送时的xml直接拼字符串得了,但是返回的xml比较奇怪,好在上面我们用postMan获取了这个返回的字符串,要稍加修改才能用Xml解析)

using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace MasCloudWs
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var ecName = "政企分公司测试";
            var apId = "demo0";
            var secretKey = "123qwe";
            var mobiles = "13800138000";
            var content = "移动改变生活。";
            var sign = "DWItALe3A";
            var addSerial = "";
            try
            {
                var mac = (ecName + apId + secretKey + mobiles + content + sign + addSerial).GetMd5();
                var xmlContent = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n" +
                                 "<s:Body>\r\n" +
                                 "<sendSms xmlns=\"http://server.webservice.service.mgw.mascloud.umpay.com/\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n" +
                                 "<arg0 xmlns=\"\">" +
                                 $"<![CDATA[<?xml version=\"1.0\" encoding=\"utf-8\"?> <WsSubmitReq><apId>{apId}</apId><secretKey>{secretKey}</secretKey><ecName>{ecName}</ecName><mobiles><string>{mobiles}</string></mobiles><content>{content}</content><sign>{sign}</sign><addSerial>{addSerial}</addSerial><mac>{mac}</mac></WsSubmitReq>]]></arg0>\r\n" +
                                 "</sendSms>\r\n" + "</s:Body>\r\n" + "</s:Envelope>";
                var url = "http://112.35.10.201:1999/smsservice";
                var stringContent = new StringContent(xmlContent, Encoding.UTF8, "text/xml");
                var httpClient = new HttpClient();
                var response = await httpClient.PostAsync(url, stringContent);
                var responseStr = await response.Content.ReadAsStringAsync();
                responseStr = responseStr.Replace("&gt;", ">").Replace("&lt;", "<").Replace("><", ">\r\n<");
                //剔除<? ?>的行,xml解析不了
                var responseXml = string.Empty;
                foreach (var str in responseStr.Split("\r\n"))
                {
                    if (str.Trim().StartsWith("<?") || str.Trim().EndsWith("?>"))
                    {
                        continue;
                    }

                    responseXml += str;
                }

                var xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(responseXml);
                var root = xmlDoc.DocumentElement;
                var successNode = root.SelectSingleNode("//success");
                if (successNode.InnerText.ToLower() == "true")
                {
                    Console.WriteLine("发送成功");
                }
                else
                {
                    var rspcodNode = root.SelectSingleNode("//rspcod");
                    Console.WriteLine("发送失败" + rspcodNode.InnerText);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            Console.ReadKey();
        }
    }

    public static class Extend
    {
        /// <summary>
        /// 计算MD5(32位小写)
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string GetMd5(this string source)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            var fromData = System.Text.Encoding.UTF8.GetBytes(source);
            var targetData = md5.ComputeHash(fromData);
            var byte2String = string.Empty;
            foreach (var data in targetData)
            {
                //这个是很常见的错误,你字节转换成字符串的时候要保证是2位宽度啊,某个字节为0转换成字符串的时候必须是00的,否则就会丢失位数啊。不仅是0,1~9也一样。
                //byte2String += targetData[i].ToString("x");//这个会丢失
                byte2String += data.ToString("x2");
            }

            return byte2String;
        }
    }
}
WS协议的

由于账号密码不对,所以是“发送失败InvalidUsrOrPwd”

 

最后,吐槽一下他们的说明文档
1、Http文档的Base64编码是错的,解码出来是这样的东西,使我以为是不是中文要转Unicode码,其实不用

 

2、先用md5加密一下是不想密码明文传输吧,但是攻击者可以根据文档提示的算法,暴力破解出密码来的

posted @ 2020-07-30 12:49  小倉唯  阅读(1223)  评论(2编辑  收藏  举报