[JAVA学习笔记-55]摘要鉴权算法

401 response
WWW-Authenticate  
realm    带
domain
nonce
opaque  带
stale
algorithm
qop-options 带
auth-param   未来扩展,目前无用



Authorization
username   用户名
realm       域名,与401一致          带
nonce 随机数,与401一致
uri 发起注册方的SIP URI
response 根据RFC2617定义的算法计算得到的MD5值
algorithm 默认“MD5”
cnonce 字符串,随机生成,由client指定,理解为client nonce
opaque 由server指定,原样带回
qop
nc nonce-count,8位16进制数,client发送的,携带nonce参数的REGISTER请求的计数(包括当前发送的请求)


【client收到REGISTER-200,server发送REGISTER-200后,dialog == null】




【response算法】
若 qop="auth" 或者 qop="auth-int":
response = "KD(MD5(A1),nonce : nc : cnonce : qop : MD5(A2))"


若 没有 qop字样:
response = "KD(MD5(A1),nonce : MD5(A2))"
=========================================================================
A1的计算方法:
若 algorithm="MD5" 或者没有指定:
A1 = username : realm : password


若 algorithm="MD5-sess":
A1 = MD5(username : realm : password : nonce : cnonce)


==========================================================================


A2的计算方法:
若 qop="auth" 或者 没有指定:
A2 = Method : uri


若 qop="auth-int":
A2 = Method : uri : MD5(entity-body)













/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package generatenonce;


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


/**
 *
 * @author liao
 */
public class GenerateNonce {


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        /*使用MD5(time-tick:SIP-rand)*/
        String rawString = new String("123456"+":"+generateSipRand());
        System.out.println(calMD5(rawString).toLowerCase());
    }
    
    public static String calMD5(String input)
    {
        byte[] inputByteArray = input.getBytes();
        byte[] outputByteArray = null;
        
        try
        {
            /*获取一个MD5转换器对象*/
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            inputByteArray = input.getBytes();
            
            messageDigest.update(inputByteArray);
            outputByteArray = messageDigest.digest();
            
            /*将字节数组转换成字符串输出*/
            return byteArrayToHex(outputByteArray);
        }
        catch (NoSuchAlgorithmException e) 
        {  
            return null; 
        } 
    }
    
    
    public static String byteArrayToHex(byte[] byteArray) 
    {  
        // 首先初始化一个字符数组,用来存放每个16进制字符  
        char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F' };  
  
  
  
        // new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))  
        char[] resultCharArray =new char[byteArray.length * 2];  


       // 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去  
  
        int index = 0;  
  
        for (byte b : byteArray) 
        {  
            resultCharArray[index++] = hexDigits[b>>> 4 & 0xf];  
            resultCharArray[index++] = hexDigits[b& 0xf];  
        }  
        
        // 字符数组组合成字符串返回 
        return new String(resultCharArray);
    }
    
    private static int generateSipRand()
    {
        int random = (int)(Math.random()*Integer.MAX_VALUE);        
        return random;
    }
}

你可能感兴趣的:([JAVA学习笔记-55]摘要鉴权算法)