怎么用Java实现Radius客户端功能
本篇内容主要讲解“怎么用Java实现Radius客户端功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用Java实现Radius客户端功能”吧!
创新互联公司提供高防服务器、云服务器、香港服务器、成都服务器托管等
实现功能
使用Java实现Radius客户端,和服务端进行交互。(当前只实现了PAP模式)
代码实现
主要代码如下: RadiusClient.java
package radius; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Code | Identifier | Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * | Authenticator | * | | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Attributes ... * +-+-+-+-+-+-+-+-+-+-+-+-+- */ public class RadiusClient { private String secret; private String ip; private int port; public RadiusClient(String secret, String ip, int port) { this.secret = secret; this.ip = ip; this.port = port; } public byte[] generateAuthRequest(PacketType packetType, String username, char[] password) throws IOException, NoSuchAlgorithmException { return getSendBytes(packetType.code, username, password); } private void receive(DatagramSocket ds) throws IOException { byte[] bs = new byte[4096]; DatagramPacket packet = new DatagramPacket(bs, bs.length); ds.receive(packet); System.out.println("receive success."); int recvType = bs[0]; if (recvType == PacketType.ACCESS_ACCEPT.code) { System.out.println(PacketType.ACCESS_ACCEPT.name()); parseResponse(bs); } else if (recvType == PacketType.ACCESS_REJECT.code) { System.out.println(PacketType.ACCESS_REJECT.name()); parseResponse(bs); } else { System.err.println("invalid response packet type: " + recvType); } } private void parseResponse(byte[] bs) { int identifier = bs[1]; int len = bs[2]; len = len << 8; len = len | bs[3]; System.out.println("response length: " + len); resolveAttr(bs, len); } private void resolveAttr(byte[] bs, int totalLen) { int index = 20; while (index < totalLen) { int type = bs[index++]; int len = bs[index++]; byte[] attrValue = new byte[len - 2]; System.arraycopy(bs, index, attrValue, 0, attrValue.length); index += attrValue.length; System.out.println(String.format("attr type: %s, value: %s", type, new String(attrValue))); } } public void send(byte[] data) { DatagramSocket ds = null; try { ds = new DatagramSocket(); DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(ip), port); ds.send(packet); System.out.println("sent success."); receive(ds); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (ds != null) { ds.close(); } } } private byte[] getSendBytes(int accessType, String username, char[] password) throws NoSuchAlgorithmException, IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); bos.write(accessType); // Code Random ran = new Random(); bos.write(ran.nextInt(255)); // Identifier // Authenticator byte[] authenticator = randomBytes(16); Listattrs = new ArrayList<>(); attrs.add(new RadiusAttr(1, username.getBytes())); // password byte[] cipherPwd = encryptPassword(password, authenticator); attrs.add(new RadiusAttr(2, cipherPwd)); int length = calculateTotalLength(attrs); // Length System.out.println("request length: " + length); int highLen = length >> 8; bos.write(highLen); bos.write(length); bos.write(authenticator); // Authenticator for (RadiusAttr attr : attrs) { bos.write(attr.getType()); bos.write(attr.length()); bos.write(attr.getValue()); } return bos.toByteArray(); } private byte[] encryptPassword(char[] pwd, byte[] authenticator) throws NoSuchAlgorithmException { if (pwd.length > 128) { throw new IllegalArgumentException("password length is too long: " + pwd.length); } byte[] pwdBytes = new String(pwd).getBytes(); List cipherBlocks = new ArrayList<>(); for (int i = 0; i < pwdBytes.length; i += 16) { byte[] pwdI = new byte[16]; int tmpLen = 16; if (i + 16 >= pwdBytes.length) { tmpLen = pwdBytes.length - i; } System.arraycopy(pwdBytes, i, pwdI, 0, tmpLen); MessageDigest md = MessageDigest.getInstance("MD5"); md.update(secret.getBytes()); if (cipherBlocks.isEmpty()) { md.update(authenticator); } else { md.update(cipherBlocks.get(cipherBlocks.size() - 1)); } byte[] md5 = md.digest(); byte[] result = new byte[16]; for (int j = 0; j < result.length; j++) { result[j] = (byte) (pwdI[j] ^ md5[j]); } cipherBlocks.add(result); } List list = new ArrayList<>(); for (byte[] bs : cipherBlocks) { for (byte b : bs) { list.add(b); } } byte[] result = new byte[list.size()]; for (int i = 0; i < result.length; i++) { result[i] = list.get(i); } return result; } private static int calculateTotalLength(List attrs) { int len = 20; // code + identifier + length + authenticator for (RadiusAttr attr : attrs) { len += attr.length(); } return len; } private static byte[] randomBytes(int length) { byte[] bs = new byte[length]; Random ran = new Random(); for (int i = 0; i < length; i++) { bs[i] = (byte) ran.nextInt(255); } return bs; } }
调用方法:
package radius; import java.io.IOException; import java.security.NoSuchAlgorithmException; public class ClientTest { public static void main(String[] args) throws IOException, NoSuchAlgorithmException { String secret = "secret"; String ip = "192.168.1.1"; int port = 1812; RadiusClient radiusClient = new RadiusClient(secret, ip, port); byte[] bs = radiusClient.generateAuthRequest(PacketType.ACCESS_REQUEST, "username", "password".toCharArray()); radiusClient.send(bs); } }
到此,相信大家对“怎么用Java实现Radius客户端功能”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
名称栏目:怎么用Java实现Radius客户端功能
本文来源:http://scyanting.com/article/pojdhd.html