Kerberos的KDC已经配置完成。
Eclipse开发工具
分别为客户端和服务端创建登录KDC的用户。使用kadmin.local工具。#kadmin.local#kadmin.local: addprinc sample/qibaofu.com@QIBAOFU.COM#kadmin.local: addprinc test1/qibaofu.com@QIBAOFU.COM创建完成后,查看用户:客户端为:test1,服务端为:sample
使用ping查看配置的主机名是否正常。此例子中,主机名为qibaofu.com,若是出现如下结果,则证明配置是正确的。
编写客户端程序。import org.ietf.jgss.*;import java.net.Socket;import java.io.IOException;import java.io.DataInputStream;import java.io.DataOutputStream;public class SampleClient { public static void main(String[] args) throws IOException, GSSException { System.setProperty('java.security.krb5.realm','QIBAOFU.COM'); System.setProperty('java.security.krb5.kdc','qibaofu.com'); System.setProperty('javax.security.auth.useSubjectCredsOnly','false'); System.setProperty('java.security.auth.login.config','bcsLogin.conf'); String server = 'sample/qibaofu.com'; String hostName = '127.0.0.1'; int port = 8090; Socket socket = new Socket(hostName, port); DataInputStream inStream = new DataInputStream(socket.getInputStream()); DataOutputStream outStream = new DataOutputStream(socket.getOutputStream()); System.out.println('Connected to server ' + socket.getInetAddress()); Oid krb5Oid = new Oid('1.2.840.113554.1.2.2'); GSSManager manager = GSSManager.getInstance(); GSSName serverName = manager.createName(server, null); GSSContext context = manager.createContext(serverName, krb5Oid, null, GSSContext.DEFAULT_LIFETIME); context.requestMutualAuth(true); // Mutual authentication context.requestConf(true); // Will use confidentiality later context.requestInteg(true); // Will use integrity later // Do the context eastablishment loop byte[] token = new byte[0]; while (!context.isEstablished()) { // token is ignored on the first call token = context.initSecContext(token, 0, token.length); // Send a token to the server if one was generated by // initSecContext if (token != null) { System.out.println('Will send token of size ' + token.length + ' from initSecContext.'); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); } // If the client is done with context establishment // then there will be no more tokens to read in this loop if (!context.isEstablished()) { token = new byte[inStream.readInt()]; System.out.println('Will read input token of size ' + token.length + ' for processing by initSecContext'); inStream.readFully(token); } } System.out.println('Context Established! '); System.out.println('Client is ' + context.getSrcName()); System.out.println('Server is ' + context.getTargName()); if (context.getMutualAuthState()) System.out.println('Mutual authentication took place!'); byte[] messageBytes = 'Hello There!\0'.getBytes(); MessageProp prop = new MessageProp(0, true); token = context.wrap(messageBytes, 0, messageBytes.length, prop); System.out.println('Will send wrap token of size ' + token.length); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); token = new byte[inStream.readInt()]; System.out.println('Will read token of size ' + token.length); inStream.readFully(token); context.verifyMIC(token, 0, token.length, messageBytes, 0, messageBytes.length, prop); System.out.println('Verified received MIC for message.'); System.out.println('Exiting...'); context.dispose(); socket.close(); }}
编写服务端程序。import org.ietf.jgss.*;import java.io.*;import java.net.Socket;import java.net.ServerSocket;public class SampleServer { public static void main(String[] args) throws IOException, GSSException { System.setProperty('java.security.krb5.realm','QIBAOFU.COM'); System.setProperty('java.security.krb5.kdc','qibaofu.com'); System.setProperty('javax.security.auth.useSubjectCredsOnly','false'); System.setProperty('java.security.auth.login.config','bcsLogin.conf'); int localPort = 8090; ServerSocket ss = new ServerSocket(localPort); GSSManager manager = GSSManager.getInstance(); while (true) { System.out.println('Waiting for incoming connection...'); Socket socket = ss.accept(); DataInputStream inStream = new DataInputStream(socket.getInputStream()); DataOutputStream outStream = new DataOutputStream(socket.getOutputStream()); System.out.println('Got connection from client ' + socket.getInetAddress()); GSSContext context = manager.createContext((GSSCredential)null); // Do the context eastablishment loop byte[] token = null; while (!context.isEstablished()) { token = new byte[inStream.readInt()]; System.out.println('Will read input token of size ' + token.length + ' for processing by acceptSecContext'); inStream.readFully(token); token = context.acceptSecContext(token, 0, token.length); // Send a token to the peer if one was generated by // acceptSecContext if (token != null) { System.out.println('Will send token of size ' + token.length + ' from acceptSecContext.'); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); } } System.out.print('Context Established! '); System.out.println('Client is ' + context.getSrcName()); System.out.println('Server is ' + context.getTargName()); if (context.getMutualAuthState()) System.out.println('Mutual authentication took place!'); MessageProp prop = new MessageProp(0, false); token = new byte[inStream.readInt()]; System.out.println('Will read token of size ' + token.length); inStream.readFully(token); byte[] bytes = context.unwrap(token, 0, token.length, prop); String str = new String(bytes); System.out.println('Received data \'' + str + '\' of length ' + str.length()); System.out.println('Confidentiality applied: ' + prop.getPrivacy()); prop.setQOP(0); token = context.getMIC(bytes, 0, bytes.length, prop); System.out.println('Will send MIC token of size ' + token.length); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); System.out.println('Closing connection with client ' + socket.getInetAddress()); context.dispose(); socket.close(); } }}
启动服务端程序,然后接着启动客户端程序。
执行客户端程序后,会提示输入用户名和密码,客户端输入后,会接着提示服务端也输入,因为此程序为互相认证,所以服务端也需要输入用户名和密码。
服务端输入密码后,此时可以发现服务可以正常执行完毕。