一、根据 选择的协议(下图是客户截图给我的,故凑合着看吧)
下载对应的文档,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(">", ">").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;
}
}
}
WS协议的
由于账号密码不对,所以是“发送失败InvalidUsrOrPwd”
最后,吐槽一下他们的说明文档
1、Http文档的Base64编码是错的,解码出来是这样的东西,使我以为是不是中文要转Unicode码,其实不用
2、先用md5加密一下是不想密码明文传输吧,但是攻击者可以根据文档提示的算法,暴力破解出密码来的