linux命令行发送脚本
#!/usr/bin/env bash
# server
aliyunSmsServer="https://dysmsapi.aliyuncs.com"
#接收方手机号
PhoneNumbers="175211112222"
#签名
SignName="权益提醒"
#短信模板
TemplateCode="SMS_11112222"
#模板参数(json格式)
TemplateParam="{\"title\":\"测试标题\"}"
AccessKeyId="AccessKeyId"
accessSecret="accessSecret"
NONCE="`uuid`"
Timestamp="`date -u '+%Y-%m-%dT%H:%M:%SZ'`"
Root="/"
# urlencode
SignName="`/bin/echo -n "${SignName}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-`"
TemplateParam="`/bin/echo -n "${TemplateParam}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-`"
Timestamp="`/bin/echo -n "${Timestamp}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-`"
RootToSign="`/bin/echo -n "${Root}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-`"
sortedQueryString="AccessKeyId=${AccessKeyId}&Action=SendSms&Format=JSON&PhoneNumbers=${PhoneNumbers}&SignName=${SignName}&SignatureMethod=HMAC-SHA256&SignatureNonce=${NONCE}&SignatureVersion=1.0&TemplateCode=${TemplateCode}&TemplateParam=${TemplateParam}&Timestamp=${Timestamp}&Version=2017-05-25"
echo "sortedQueryString = ${sortedQueryString}"
# urlencode
sortedQueryStringToSign="`/bin/echo -n "${sortedQueryString}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3- | sed 's/\+/%20/g' | sed 's/\*/%2A/g' | sed 's/%7E/~/g'`"
echo "sortedQueryStringToSign = ${sortedQueryStringToSign}"
stringToSign="GET&${RootToSign}&${sortedQueryStringToSign}"
echo "stringToSign = ${stringToSign}"
sign="`/bin/echo -n "${stringToSign}" | openssl dgst -sha256 -hmac "${accessSecret}&" -binary | base64`"
signature="`/bin/echo -n "${sign}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3- | sed 's/\+/%20/g' | sed 's/\*/%2A/g' | sed 's/%7E/~/g'`"
url="${aliyunSmsServer}/?Signature=${signature}&${sortedQueryString}"
echo "${url}"
curl -v "${url}"
echo ""
Java-RestTemplate方式发送短信
@Configuration
public class AliyunSmsConfig {
public static void main1(String[] args) throws Exception {
/**
* 测试阿里云短信SDK发送
*/
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config().setAccessKeyId("accessKeyId").setAccessKeySecret("accessSecret").setProtocol(ProtocolType.HTTP);
config.endpoint = "dysmsapi.aliyuncs.com";
Client client = new Client(config);
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions().setHttpProxy("http://127.0.0.1:8888").setHttpsProxy("http://127.0.0.1:8888").setAutoretry(true).setMaxAttempts(3);
com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
.setSignName("权益提醒")//签名
.setTemplateCode("SMS_11112222")//模板code
.setPhoneNumbers("17511112222")//手机号
.setTemplateParam("{\"title\":\"测试标题\"}");//模板参数
com.aliyun.dysmsapi20170525.models.SendSmsResponse resp = client.sendSmsWithOptions(sendSmsRequest, runtime);
System.out.println("测试发送短信,返回结果");
System.out.println(JSONObject.toJSONString(resp));
}
public static void main(String[] args) throws Exception {
/**
* 测试阿里云短信WebApi发送
*/
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));// 这里一定要设置GMT时区
String accessKeyId = "accessKeyId";
String accessSecret = "accessSecret";
String endpoint = "https://dysmsapi.aliyuncs.com";
String PhoneNumbers = "17511112222";
String SignName = "权益提醒";
String TemplateCode = "SMS_111122227";
String TemplateParam = "{\"title\":\"测试标题\"}";
java.util.Map<String, String> paras = new java.util.HashMap<String, String>();
// 1. 系统参数
paras.put("SignatureMethod", "HMAC-SHA256");
paras.put("SignatureNonce", java.util.UUID.randomUUID().toString());
paras.put("AccessKeyId", accessKeyId);
paras.put("SignatureVersion", "1.0");
paras.put("Timestamp", df.format(new java.util.Date()));
paras.put("Format", "JSON");
// 2. 业务API参数
paras.put("Action", "SendSms");
paras.put("Version", "2017-05-25");
paras.put("RegionId", "");
paras.put("PhoneNumbers", PhoneNumbers);
paras.put("SignName", SignName);
paras.put("TemplateParam", TemplateParam);
paras.put("TemplateCode", TemplateCode);
// 3. 去除签名关键字Key
if (paras.containsKey("Signature"))
paras.remove("Signature");
// 4. 参数KEY排序
java.util.TreeMap<String, String> sortParas = new java.util.TreeMap<String, String>();
sortParas.putAll(paras);
// 5. 构造待签名的字符串
java.util.Iterator<String> it = sortParas.keySet().iterator();
StringBuilder sortQueryStringTmp = new StringBuilder();
while (it.hasNext()) {
String key = it.next();
sortQueryStringTmp.append("&").append(specialUrlEncode(key)).append("=").append(specialUrlEncode(paras.get(key)));
}
String sortedQueryString = sortQueryStringTmp.substring(1);// 去除第一个多余的&符号
StringBuilder stringToSign = new StringBuilder();
stringToSign.append("GET").append("&");
stringToSign.append(specialUrlEncode("/")).append("&");
stringToSign.append(specialUrlEncode(sortedQueryString));
String sign = sign(accessSecret + "&", stringToSign.toString());
// 6. 签名最后也要做特殊URL编码
String signature = specialUrlEncode(sign);
//7.请求
String url = endpoint + "/?Signature=" + signature + sortQueryStringTmp;
// 最终打印出合法GET请求的URL
System.out.println(endpoint + "/?Signature=" + signature + sortQueryStringTmp);
RestTemplate restTemplate = endpoint.startsWith("https") ? new RestTemplate(new HttpsClientRequestFactory()) : new RestTemplate();
String data = restTemplate.getForObject(new URI(url), String.class);
System.out.println("阿里短信 By Web API sendSMS return = response.getData :" + data);
}
private static String specialUrlEncode(String value) throws Exception {
return java.net.URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
}
private static String sign(String accessSecret, String stringToSign) throws Exception {
javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA256");
mac.init(new javax.crypto.spec.SecretKeySpec(accessSecret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
return new sun.misc.BASE64Encoder().encode(signData);
}
public static class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) {
try {
if (!(connection instanceof HttpsURLConnection)) {
throw new RuntimeException("An instance of HttpsURLConnection is expected");
}
HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
httpsConnection.setSSLSocketFactory(new MyCustomSSLSocketFactory(sslContext.getSocketFactory()));
httpsConnection.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
super.prepareConnection(httpsConnection, httpMethod);
} catch (Exception e) {
e.printStackTrace();
}
}
private static class MyCustomSSLSocketFactory extends SSLSocketFactory {
private final SSLSocketFactory delegate;
public MyCustomSSLSocketFactory(SSLSocketFactory delegate) {
this.delegate = delegate;
}
// 返回默认启用的密码套件。除非一个列表启用,对SSL连接的握手会使用这些密码套件。
// 这些默认的服务的最低质量要求保密保护和服务器身份验证
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
// 返回的密码套件可用于SSL连接启用的名字
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(final Socket socket, final String host, final int port,
final boolean autoClose) throws IOException {
final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose);
return overrideProtocol(underlyingSocket);
}
@Override
public Socket createSocket(final String host, final int port) throws IOException {
final Socket underlyingSocket = delegate.createSocket(host, port);
return overrideProtocol(underlyingSocket);
}
@Override
public Socket createSocket(final String host, final int port, final InetAddress localAddress,
final int localPort) throws
IOException {
final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
return overrideProtocol(underlyingSocket);
}
@Override
public Socket createSocket(final InetAddress host, final int port) throws IOException {
final Socket underlyingSocket = delegate.createSocket(host, port);
return overrideProtocol(underlyingSocket);
}
@Override
public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress,
final int localPort) throws
IOException {
final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
return overrideProtocol(underlyingSocket);
}
private Socket overrideProtocol(final Socket socket) {
if (!(socket instanceof SSLSocket)) {
throw new RuntimeException("An instance of SSLSocket is expected");
}
//((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"});
return socket;
}
}
}
}