阿里云网关签名特殊字符无法通过

原代码

public static String sendByPost(String url, int soTimeout, int connectTimeout, String goodsSerial) {
		// logger.info("请求地址为:" + url);
		String bodyString = "{\"sku\":[\"" + goodsSerial + "\"]}";

		String stringToSign = "";
		String date = new Date().toGMTString();
		Long currentTimeMillis = System.currentTimeMillis();
			MessageDigest md = MessageDigest.getInstance(MessageDigestAlgorithms.MD5);
			String contentMD5 = new String(Base64.getEncoder().encode(md.digest(bodyString.getBytes())));
			System.out.println(bodyString);
			String[] split = url.split("com");
			// HTTP请求URI
			HttpPost request = new HttpPost(url);
			request.addHeader("Authorization", token );

			request.addHeader("Accept", "application/json; charset=utf-8");
			request.addHeader("Content-MD5", contentMD5);
			request.addHeader("Date", date);
			request.addHeader("content-type", "application/json; charset=utf-8"); 
			request.addHeader("PathAndParameters", split[split.length - 1]);
			request.addHeader("x-ca-key", appKey);
			request.addHeader("x-ca-signature-method", "HmacSHA256");
			request.addHeader("x-ca-signature-headers", "x-ca-signature-method,x-ca-timestamp,x-ca-key,");
			request.addHeader("x-ca-timestamp", currentTimeMillis.toString());

			
			stringToSign = "POST" + "\napplication/json; charset=utf-8\n" + contentMD5
					+ "\napplication/json; charset=utf-8\n" + date + "\nx-ca-key:203837880"
					+ "\nx-ca-signature-method:HmacSHA256" + "\nx-ca-timestamp:" + currentTimeMillis + "\n"
					+ split[split.length - 1];
			try {
				Mac hmacSha256 = Mac.getInstance("HmacSHA256");
				hmacSha256.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256"));
				byte[] md5Result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
				String sign = new String(Base64.getEncoder().encode(md5Result));
				request.addHeader("X-Ca-Signature", sign);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			request.setEntity(new StringEntity(bodyString ));
			String message = sendRequest(request, soTimeout, connectTimeout);
			// logger.info(",请求结果为:=" + message);
			return message;
			} catch (Exception e) {
			e.printStackTrace();
			logger.info(",请求结果为:=" + e);
		}
		return null;
	}

经测试发现对中文字符无法通过Content-MD5的签名认证,返回为Content-MD5验证失败
比如传输 A108662-12×500ml 则显示返回Content-MD5验证失败,A108662则可以通过验证。
但是使用postman可以直接通过。
猜想为中文字符的部分在传输时被转为unicode,然后在阿里云验证时候使用的unicode去进行加密验证,而postman能通过则是因为他传输的是流,application/json请求头传输流。
于是我替换

request.setEntity(new StringEntity(bodyString ));

request.setEntity(new ByteArrayEntity(bodyString.getBytes()));

这样可以通过阿里云验证,但是返回的结果会将特殊字符及中文转为unicode编码
于是我们需要手动将unicode部分转为中文
上最终代码

public static String sendAlaDinByPost(String url, int soTimeout, int connectTimeout, String goodsSerial) {
		// logger.info("请求地址为:" + url);
		String bodyString = "{\"sku\":[\"" + goodsSerial + "\"]}";

		String stringToSign = "";
		String date = new Date().toGMTString();
		Long currentTimeMillis = System.currentTimeMillis();
			MessageDigest md = MessageDigest.getInstance(MessageDigestAlgorithms.MD5);
			String contentMD5 = new String(Base64.getEncoder().encode(md.digest(bodyString.getBytes())));
			System.out.println(bodyString);
			String[] split = url.split("com");
			// HTTP请求URI
			HttpPost request = new HttpPost(url);
			request.addHeader("Authorization", token );

			request.addHeader("Accept", "application/json; charset=utf-8");
			request.addHeader("Content-MD5", contentMD5);
			request.addHeader("Date", date);
			request.addHeader("content-type", "application/json; charset=utf-8"); 
			request.addHeader("PathAndParameters", split[split.length - 1]);
			request.addHeader("x-ca-key", appKey);
			request.addHeader("x-ca-signature-method", "HmacSHA256");
			request.addHeader("x-ca-signature-headers", "x-ca-signature-method,x-ca-timestamp,x-ca-key,");
			request.addHeader("x-ca-timestamp", currentTimeMillis.toString());

			
			stringToSign = "POST" + "\napplication/json; charset=utf-8\n" + contentMD5
					+ "\napplication/json; charset=utf-8\n" + date + "\nx-ca-key:203837880"
					+ "\nx-ca-signature-method:HmacSHA256" + "\nx-ca-timestamp:" + currentTimeMillis + "\n"
					+ split[split.length - 1];
			try {
				Mac hmacSha256 = Mac.getInstance("HmacSHA256");
				hmacSha256.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256"));
				byte[] md5Result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
				String sign = new String(Base64.getEncoder().encode(md5Result));
				request.addHeader("X-Ca-Signature", sign);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			request.setEntity(new ByteArrayEntity(bodyString.getBytes()));
			String message = sendRequest(request, soTimeout, connectTimeout);
			// logger.info(",请求结果为:=" + message);
			return StringUtil.decodeUnicode(message);
			} catch (Exception e) {
			e.printStackTrace();
			logger.info(",请求结果为:=" + e);
		}
		return null;
	}

stringutil

public static String decodeUnicode(String unicodeStr) {
		Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
		Matcher matcher = pattern.matcher(unicodeStr);
		char ch;
		while (matcher.find()) {
			// group
			String group = matcher.group(2);
			// ch:'李四'
			ch = (char) Integer.parseInt(group, 16);
			// group1 
			String group1 = matcher.group(1); 
			unicodeStr = unicodeStr.replace("\\"+group1, ch + "");
		}

		return unicodeStr.trim();
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值