记录摘要认证的实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

记录摘要认证的实现,用于海康录像机获取抓拍图片。

一、代码

1.引入包

代码如下(示例):

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import cn.hutool.http.Method;

2.代码

代码如下:

	String m_sUsername = "用户名";// 用户名
	String m_sPassword = "密码";// 密码
//通过url从设备获取图片
	    private byte[] getStreamFromUrl(String picUrl,String uri) {
	        URL url = null;
	        byte[] data = null;
	        InputStream inStream = null;
			try {
//	          第一次请求
				url = new URL(picUrl);
				HttpURLConnection conn = (HttpURLConnection)url.openConnection();
	                //超时响应时间为3秒
	              conn.setConnectTimeout(3 * 1000);
	              if(conn.getResponseCode()==401) {
	            	  System.out.println("返回401,设备已开启摘要认证");
//	            	  摘要认证
	                  Map<String, List<String>> headerFields = conn.getHeaderFields();
	                  List<String> au = headerFields.get("WWW-Authenticate");
	                  conn.disconnect();
	                  String auth = au.get(0);
	                  HashMap<String, String> authFields = splitAuthFields(auth.substring(7));
	                  String A1 = null; 
	                  String A2 = null; 
	                  String response = null; 
	                  MessageDigest md5 = null;
//	                  第一次摘要认证请求
	                  String nc = "00000001";
//	                  可以修改
	                  String cnonce = "0123abcd";
	                  
	                  try {
	                      md5 = MessageDigest.getInstance("MD5");
	                  } catch (NoSuchAlgorithmException e) {
	                      e.printStackTrace();
	                  }
//	                  拼接字符串A1
	                  try {
	                      md5.reset();
	                      String A1Str = m_sUsername+":"+authFields.get("realm")+":"+m_sPassword;
	                      md5.update(A1Str.getBytes());
	                      System.out.println("A1Str:"+A1Str);
	                      A1 = bytesToHexString(md5.digest());
	                  } catch (Exception e) {
	                 	 e.printStackTrace();
	                  }
//	                  拼接字符串A2
	                  try {
	                      md5.reset();
	                      String A2Str = Method.GET.toString()+":"+ uri;
	                      md5.update(A2Str.getBytes());
	                      A2 = bytesToHexString(md5.digest());
	                  } catch (Exception e) {
	                 	 e.printStackTrace();
	                  }
//	                  拼接最终字符串
	                  try {
	                      md5.reset();
	                      StringBuilder s0 = new StringBuilder(A1);
	                      s0.append(":").append(authFields.get("nonce")).append(":");
	                      s0.append(nc).append(":");
	                      s0.append(cnonce).append(":");
	                      s0.append(authFields.get("qop")).append(":");
	                      s0.append(A2);
	                      String reStr = s0.toString();
	                      md5.update(reStr.getBytes());
	                      response = bytesToHexString(md5.digest());
	                  } catch (Exception e) {
	                 	 e.printStackTrace();
	                  }
	                  // 拼接 Authorization Header
	                  StringBuilder sb = new StringBuilder();
	                  sb.append("Digest ");
	                  sb.append("username").append("=\"").append(m_sUsername).append("\",");
	                  sb.append("realm").append("=\"").append(authFields.get("realm")).append("\",");
	                  sb.append("qop").append("=\"").append(authFields.get("qop")).append("\",");
	                  sb.append("nonce").append("=\"").append(authFields.get("nonce")).append("\",");
	                  sb.append("uri").append("=\"").append(uri).append("\",");
	                  sb.append("algorithm").append("=\"").append("MD5").append("\",");
	                  sb.append("nc").append("=\"").append(nc).append("\",");
	                  sb.append("cnonce").append("=\"").append(cnonce).append("\",");
	                  sb.append("response").append("=\"").append(response).append("\"");
//	                  再次请求
	                  HttpURLConnection conn1 = null;
	                  try {
	                  	URL url1 = new URL(picUrl);
	                  	conn1 = (HttpURLConnection)url1.openConnection();
	          			conn1.setRequestProperty("Authorization", sb.toString());
	                         //超时响应时间为3秒
	                      conn1.setConnectTimeout(3 * 1000);
	                      conn1.connect();
//	                      获取输入流
	                 	  inStream = conn1.getInputStream();
	                      data = readInputStream(inStream);
	                      //关闭输入流
	                      inStream.close();
//	                      关闭连接
	                      conn1.disconnect();
	 				} catch (Exception e) {
	 					System.out.println(e);
	 					System.out.println(conn1.getResponseCode());
	 					InputStream errorStream = conn1.getErrorStream();
	 					System.out.println(IOUtils.toString(errorStream, "UTF-8"));
	 				}
	              }else if(conn.getResponseCode()==200){
	            	  System.out.println("设备未开启摘要认证");
	             	  inStream = conn.getInputStream();
	                  data = readInputStream(inStream);
	                  //关闭输入流
	                  inStream.close();
//                      关闭连接
	                  conn.disconnect();
	              }
	 
			} catch (Exception e) {
				e.printStackTrace();
			}
	    	return data;
	    }
//	    读取输入流,转为byte数组
		private static byte[] readInputStream(InputStream inStream) throws Exception {
	        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
	        byte[] buffer = new byte[4096];
	        //每次读取的字符串长度,如果为-1,代表全部读取完毕
	        int len = 0;
	        //使用一个输入流从buffer里把数据读取出来
	        while ((len = inStream.read(buffer)) != -1) {
	            //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
	            outStream.write(buffer, 0, len);
	        }
	        byte[] byteArray = outStream.toByteArray();
	        outStream.close();
	        //把outStream里的数据写入内存
	        return byteArray;
		}
	    private static final String HEX_LOOKUP = "0123456789abcdef";
	    private static String bytesToHexString(byte[] bytes) {
	        StringBuilder sb = new StringBuilder();
	        for (int i = 0; i < bytes.length; i++) {
	            sb.append(HEX_LOOKUP.charAt((bytes[i] & 0xF0) >> 4));
	            sb.append(HEX_LOOKUP.charAt((bytes[i] & 0x0F) >> 0));
	        }
	        return sb.toString();
	    }
//	    将AuthFields(字符串)中的数据转化为Map
	    private static HashMap<String, String> splitAuthFields(String raw) {
	        final HashMap<String, String> fields = new HashMap<String, String>();
	        String[] str = raw.trim().split(",");
	        for (String s : str) {
				String[] item = s.trim().split("=");
				fields.put(item[0], item[1].replaceAll("\"", ""));
			}
	        return fields;
	    }

---


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值