gpt4 book ai didi

java - RADIUS 库未正确加密或编码密码字符串

转载 作者:行者123 更新时间:2023-11-30 08:12:44 37 4
gpt4 key购买 nike

我目前正在从事一个涉及使用 Java 和 Python 对 RADIUS 服务器进行直接身份验证的项目。

我的 Python 实现工作正常,但是我已经尝试了两个 Java库(TinyRADIUS 和 JRaD),两者表现出相同的行为:

当发送 PAP 请求时,密码中前 16 位之后的所有字符似乎都变成了乱码或半 UTF 编码,导致服务器无法通过身份验证。

见下文:

    JRaDclient rc = new JRaDclient();

rc.setSecretKey("secrets");
rc.setServer("127.0.0.1", 1812);
rc.authenticate("testuser", "pass123LogeuCcoboJKidoDeVFesekSoluneCgaLttrjhrkrhn");

然而,服务器上的结果请求变成了这个

rad_recv: Access-Request packet from host 127.0.0.1 port 1337, id=210, length=96
User-Name = "testuser"
User-Password = "pass123LogeuCcob\275\213?\353\210\352A1\333mP\266\253P[h\234zL\3021/\373\001\334\032\263\033BuKM\022\t\233\261r\301\3035
6\267\333+W'b\221"

这是库的同时问题还是 Radius 的配置/版本问题?

作为引用,这是在 Java 8 上运行的,带有 FreeRADIUS v2.1.12。

JRaD:https://github.com/punyal/JRaD微小半径:http://tinyradius.sourceforge.net/

最佳答案

当密码超过 16 个字符时会出现问题 - 密码编码填充密码然后对其进行加密,这是不正确的。

我们在项目中包含了源代码,并替换了 pap 密码编码和 pap 密码解码方法(本质上,在填充之前加密密码,而不是用填充加密)。

基于此:http://sourceforge.net/p/tinyradius/discussion/461293/thread/dcedb4ed/

修改后的相关代码如下:

    /**
* This method encodes the plaintext user password according to RFC 2865.
*
* @param userPass
* the password to encrypt
* @param sharedSecret
* shared secret
* @return the byte array containing the encrypted password
*/
private byte[] encodePapPassword(final byte[] userPass, byte[] sharedSecret) {
// the password must be a multiple of 16 bytes and less than or equal
// to 128 bytes. If it isn't a multiple of 16 bytes fill it out with zeroes
// to make it a multiple of 16 bytes. If it is greater than 128 bytes
// truncate it at 128.


if (userPass == null) {
throw new IllegalArgumentException("password is null");
} else if (sharedSecret == null) {
throw new IllegalArgumentException("shared secret is null");
} else if (getAuthenticator() == null) {
throw new IllegalArgumentException("authenticator is null");
}

byte[] userPassBytes = null;
if (userPass.length > 128) {
userPassBytes = new byte[128];
System.arraycopy(userPass, 0, userPassBytes, 0, 128);
} else {
userPassBytes = userPass;
}
// declare the byte array to hold the final product
byte[] encryptedPass = null;
if (userPassBytes.length < 128) {
if (userPassBytes.length % 16 == 0) {
// tt is already a multiple of 16 bytes
encryptedPass = new byte[userPassBytes.length];
} else {
// make it a multiple of 16 bytes
encryptedPass = new byte[((userPassBytes.length / 16) * 16) + 16];
}
} else {
// the encrypted password must be between 16 and 128 bytes
encryptedPass = new byte[128];
}
// copy the userPass into the encrypted pass and then fill it out with zeroes
System.arraycopy(userPassBytes, 0, encryptedPass, 0, userPassBytes.length);
for (int i = userPassBytes.length; i < encryptedPass.length; i++) {
encryptedPass[i] = 0;
}
// digest shared secret and authenticator
MessageDigest md5 = getMd5Digest();

md5.reset();
byte[] bn = new byte[sharedSecret.length + getAuthenticator().length];
for (int i = 0; i < bn.length; i++) {
if (i < sharedSecret.length)
bn[i] = sharedSecret[i];
else
bn[i] = getAuthenticator()[i - sharedSecret.length];
}
md5.update(bn);
bn = md5.digest();
// perform the XOR as specified by RFC 2865
for (int i = 0; i < 16; i++) {
encryptedPass[i] = (byte) (bn[i] ^ encryptedPass[i]);
}
if (encryptedPass.length > 16) {
for (int i = 16; i < encryptedPass.length; i += 16) {
md5.reset();
md5.update(sharedSecret);
// add the previous (encrypted) 16 bytes of the user password
md5.update(encryptedPass, i - 16, 16);
bn = md5.digest();
// perform the XOR as specified by RFC 2865.
for (int j = 0; j < 16; j++) {
encryptedPass[i + j] = (byte) (bn[j] ^ encryptedPass[i + j]);
}
}
}
return encryptedPass;
}

/**
* Decodes the passed encrypted password and returns the clear-text form.
*
* @param encryptedPass
* encrypted password
* @param sharedSecret
* shared secret
* @return decrypted password
*/
private String decodePapPassword(byte[] encryptedPass, byte[] sharedSecret) throws RadiusException {
if (encryptedPass == null) {
throw new IllegalArgumentException("encrypted password is null");
} else if (sharedSecret == null) {
throw new IllegalArgumentException("shared secret is null");
} else if (getAuthenticator() == null) {
throw new IllegalArgumentException("authenticator is null");
} else if (encryptedPass.length < 16) {
throw new IllegalArgumentException("invalid length of encrypted pass: " + encryptedPass.length);
}

// save original (encoded) encrypted pass
byte[] encryptedPassOrig = encryptedPass.clone();
// MessageDigest md5;
MessageDigest md5 = getMd5Digest();
md5.reset();
md5.update(sharedSecret);
md5.update(getAuthenticator());
byte bn[] = md5.digest();
// perform the XOR as specified by RFC 2865
for (int i = 0; i < 16; i++) {
encryptedPass[i] = (byte) (bn[i] ^ encryptedPass[i]);
}
if (encryptedPass.length > 16) {
for (int i = 16; i < encryptedPass.length; i += 16) {
md5.reset();
md5.update(sharedSecret);
// now use original (encoded) pass to generate MD5
md5.update(encryptedPassOrig, i - 16, 16);
bn = md5.digest();
// perform the XOR as specified by RFC 2865.
for (int j = 0; j < 16; j++) {
encryptedPass[i + j] = (byte) (bn[j] ^ encryptedPass[i + j]);
}
}
}
// remove trailing zeros
int len = encryptedPass.length;
while (len > 0 && encryptedPass[len - 1] == 0) {
len--;
}

byte[] passtrunc = new byte[len];
System.arraycopy(encryptedPass, 0, passtrunc, 0, len);
// convert to string
return RadiusUtil.getStringFromUtf8(passtrunc);
}

关于java - RADIUS 库未正确加密或编码密码字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30289816/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com