Java 6 SE 里的DigestAuthentication[1]


Java 6 SE 里的DigestAuthentication[1]

Author:zfive5
Email:zfive5@yahoo.com.cn

两三年前,看过一阵子java,同时也分析过java sdk的源码,当时为什么看jdbc是怎样实现的,今天在csdn看到什么13篇文章,看到java 6 SE支持ntlm

 

同是也看到了Digest,一下子兴趣就来,马上到sun的网站download一个jdk 6 se的代码. java的大部分代码都是java,还有很少一部分是c写的(这部分主要是和平台有关的)

 

命令行下运行:

 

C:/>java -jar C:/jdk-6u2-fcs-src-b05-jrl-22_jun_2007.jar

 

根据提示指定解压目录就可以.

 

WindowsNTLM下居然用的是msdll,如下:

 

    OSVERSIONINFO   version;

    UCHAR libName[MAX_PATH];

 

    ntlm_ctxHandleID = (*env)->GetFieldID(env, clazz, "ctxHandle", "J");

    ntlm_crdHandleID = (*env)->GetFieldID(env, clazz, "crdHandle", "J");

 

    version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);

    GetVersionEx (&version);

 

    if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {

       strcpy (libName, "security.dll" );

    }

    else if (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {

       strcpy (libName, "secur32.dll" );

    }

 

    lib = LoadLibrary (libName);

 

    pFreeCredentialsHandle

       = (FREE_CREDENTIALS_HANDLE_FN) GetProcAddress(

       lib, "FreeCredentialsHandle" );

 

    pAcquireCredentialsHandle

       = (ACQUIRE_CREDENTIALS_HANDLE_FN) GetProcAddress(

       lib, "AcquireCredentialsHandleA" );

 

    pFreeContextBuffer

       = (FREE_CONTEXT_BUFFER_FN) GetProcAddress(

       lib, "FreeContextBuffer" );

 

    pInitializeSecurityContext

       = (INITIALIZE_SECURITY_CONTEXT_FN) GetProcAddress(

       lib, "InitializeSecurityContextA" );

 

    pCompleteAuthToken

       = (COMPLETE_AUTH_TOKEN_FN) GetProcAddress(

       lib, "CompleteAuthToken" );

 

    pDeleteSecurityContext

       = (DELETE_SECURITY_CONTEXT_FN) GetProcAddress(

       lib, "DeleteSecurityContext" );

 

这样的实现写法的确可以节省代码和时间,但自己一步步的实现绝对不是没有必要. solaris下的实现就完全是java写的.

 

下面的注释才可以了解一下http认证原理:

 

/**

     * Returns the String that should be included in the HTTP

     * <B>Authorization</B> field.  Return null if no info was

     * supplied or could be found.

     * <P>

     * Example:

     * --> GET http://www.authorization-required.com/ HTTP/1.0

     * <-- HTTP/1.0 403 Unauthorized

     * <-- WWW-Authenticate: Basic realm="WallyWorld"

     * call schemeSupported("Basic"); (return true)

     * call authString(u, "Basic", "WallyWorld", null);

     *   return "QWadhgWERghghWERfdfQ=="

     * --> GET http://www.authorization-required.com/ HTTP/1.0

     * --> Authorization: Basic QWadhgWERghghWERfdfQ==

     * <-- HTTP/1.0 200 OK

     * <B> YAY!!!</B>

     */

 

其实这次重点不是以上而是DigestAuthentication

现在首先用pd12分析一下类结构,如下:

 

https://p-blog.csdn.net/images/p_blog_csdn_net/zfive5/72680/o_zfive5java.jpg

 

 

待续….

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Java进行DS-8632N-I16-V2的digest认证的示例代码: ```java import java.io.*; import java.net.*; import java.security.*; import java.util.*; import org.apache.commons.codec.binary.Base64; public class DigestAuthentication { private static String username = "admin"; private static String password = "password"; private static String host = "192.168.1.100"; private static int port = 80; private static String realm = ""; private static String nonce = ""; private static String qop = ""; private static String algorithm = "MD5"; private static String opaque = ""; public static void main(String[] args) { try { // 发送GET请求获取realm、nonce等参数 HttpURLConnection connection = (HttpURLConnection) new URL("http://" + host + ":" + port).openConnection(); connection.setRequestMethod("GET"); connection.connect(); String authenticate = connection.getHeaderField("WWW-Authenticate"); if (authenticate != null && authenticate.startsWith("Digest")) { Scanner scanner = new Scanner(authenticate.substring(7)); scanner.useDelimiter(", "); while (scanner.hasNext()) { String[] pair = scanner.next().split("="); if (pair.length == 2) { String name = pair[0].substring(1, pair[0].length() - 1); String value = pair[1].substring(1, pair[1].length() - 1); if ("realm".equals(name)) { realm = value; } else if ("nonce".equals(name)) { nonce = value; } else if ("qop".equals(name)) { qop = value; } else if ("algorithm".equals(name)) { algorithm = value; } else if ("opaque".equals(name)) { opaque = value; } } } } connection.disconnect(); // 发送POST请求进行认证 String ha1 = md5sum(username + ":" + realm + ":" + password); String ha2 = md5sum("GET:/ISAPI/System/deviceInfo"); String response = md5sum(ha1 + ":" + nonce + ":" + "00000001" + ":" + "xyz" + ":" + qop + ":" + ha2); connection = (HttpURLConnection) new URL("http://" + host + ":" + port + "/ISAPI/System/deviceInfo").openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Authorization", "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"/ISAPI/System/deviceInfo\", qop=" + qop + ", algorithm=" + algorithm + ", opaque=\"" + opaque + "\", nc=00000001, cnonce=\"xyz\", response=\"" + response + "\""); connection.setDoOutput(true); connection.connect(); InputStream inputStream = connection.getInputStream(); String result = new Scanner(inputStream).useDelimiter("\\A").next(); System.out.println(result); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } } private static String md5sum(String text) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(text.getBytes()); byte[] digest = md.digest(); return Base64.encodeBase64String(digest); } } ``` 请根据实际情况修改代码中的用户名、密码、主机名、端口号等参数。注意,要使用Apache Commons Codec库中的Base64类进行Base64编码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值