一、根據 選擇的協議(下圖是客戶截圖給我的,故湊合着看吧)
下載對應的文檔,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; } } }
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(">", ">").Replace("<", "<").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; } } }
由於賬號密碼不對,所以是“發送失敗InvalidUsrOrPwd”
最后,吐槽一下他們的說明文檔
1、Http文檔的Base64編碼是錯的,解碼出來是這樣的東西,使我以為是不是中文要轉Unicode碼,其實不用
2、先用md5加密一下是不想密碼明文傳輸吧,但是攻擊者可以根據文檔提示的算法,暴力破解出密碼來的