在Java中如何将SID转换为字符串,反之亦然?

发布于 2024-11-30 09:30:32 字数 394 浏览 5 评论 0原文

我正在使用 Spring-LDAP 用 Ja​​va 编写一个程序。我需要实现一个方法,该方法应该通过 SID 搜索用户。因此,我使用像 "&((objectClass=User)(objectSid="+sid+"))" 这样的过滤器。搜索不适用于字符串格式的 sid,例如 "S-1-12-345677-5676743-223344-..."

使用 Apache Directory Studio,我可以使用如下过滤器定期查询我的 AD LDAP 数据库:(objectSid=\ff\01\03\04\1a\2b\...) 成功。这是十六进制格式的 objectSid。

现在,如何在 Java 程序中将 SID 从字符串转换为十六进制,反之亦然?

I'm writing a program in Java, using Spring-LDAP. I need to implement a method, which should search a user by SID. For this reason I use a filter like "&((objectClass=User)(objectSid="+sid+"))". The search doesn't work with sid in String format like "S-1-12-345677-5676743-223344-...".

Using Apache Directory Studio, I can query my AD LDAP database regulary using a filter like: (objectSid=\ff\01\03\04\1a\2b\...) successfully. Here is the objectSid in hexadecimal format.

Now, how to translate the SID from String to hexadecimal and vice versa in a program, in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

故事还在继续 2024-12-07 09:30:32

Advapi32Util 类。

我不确定这是否正是您需要的格式,但希望能让您更接近。

这里有一篇描述 SID 的博客文章格式可能会有所帮助。

There's the convertSidToStringSid and convertStringSidToSid methods in the Advapi32Util class.

I'm not sure if that'll be the exact formats you need, but hopefully will get you closer.

And here's an blog post that describes the SID format which might be helpful.

或十年 2024-12-07 09:30:32

ho1(使用 Advapi32Util)类建议的解决方案有两个限制:

  1. 它需要 JNA 库。
  2. 它仅在 Windows 平台上运行时才有效,因为它使用 Windows-API。

因此,我编写了一个纯Java的类,没有外部依赖,并且可以在所有平台上运行。此类可以将安全标识符从二进制表示转换为文本表示,反之亦然。

如果您使用 Spring-LDAP,您还可以使用 LdapUtils 类提供的方法,但是这些方法不会对 SID 的格式执行任何检查,因此可能会产生不正确的结果或意外的异常。

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class SidConverter {

    private final static int MASK_8_BIT = 0xff;
    private final static long MASK_32_BIT = 0xffffffffL;
    private final static long MASK_48_BIT = 0xffffffffffffL;

    public static String bytesToString(byte[] bytes) {
        if (bytes.length < 8) {
            throw new IllegalArgumentException(
                    "Binary SID representation must have at least 8 bytes but passed byte array has only "
                            + bytes.length + " bytes.");
        }
        // The revision number is an unsigned 8-bit unsigned integer.
        int revision = bytes[0] & MASK_8_BIT;
        // The number of sub-authority parts is specified as an 8-bit unsigned
        // integer.
        int numberOfSubAuthorityParts = bytes[1] & MASK_8_BIT;
        if (bytes.length != 8 + numberOfSubAuthorityParts * 4) {
            throw new IllegalArgumentException(
                    "According to byte 1 of the SID it total length should be "
                            + (8 + 4 * numberOfSubAuthorityParts)
                            + " bytes, however its actual length is "
                            + bytes.length + " bytes.");
        }
        // The authority is a 48-bit unsigned integer stored in big-endian
        // format.
        long authority = ByteBuffer.wrap(bytes).getLong() & MASK_48_BIT;
        // The sub-authority consists of up to 255 32-bit unsigned integers in
        // little-endian format. The number of integers is specified by
        // numberOfSubAuthorityParts.
        int[] subAuthority = new int[numberOfSubAuthorityParts];
        ByteBuffer.wrap(bytes, 8, bytes.length - 8)
                .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().put(subAuthority);
        StringBuilder sb = new StringBuilder();
        sb.append("S-");
        sb.append(revision);
        sb.append("-");
        sb.append(authority);
        for (int subAuthorityPart : subAuthority) {
            sb.append("-");
            sb.append(subAuthorityPart & MASK_32_BIT);
        }
        return sb.toString();
    }

    public static byte[] stringToBytes(String sid) {
        if (!sid.startsWith("S-") && !sid.startsWith("s-")) {
            throw new IllegalArgumentException("Invalid SID \"" + sid
                    + "\": A valid SID must start with \"S-\".");
        }
        String[] parts = sid.split("-");
        if (parts.length < 3) {
            throw new IllegalArgumentException("Invalid SID \"" + sid
                    + "\": A valid SID must have at least two dashes.");
        }
        if (parts.length > MASK_8_BIT + 3) {
            throw new IllegalArgumentException("Invalid SID \"" + sid
                    + "\": A valid SID must not have more than 257 dashes.");
        }
        int revision;
        try {
            revision = Integer.parseInt(parts[1]);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    "Invalid revision part in SID \""
                            + sid
                            + "\": The revision must be an integer number between 0 and 255.");
        }
        if (revision < 0 || revision > MASK_8_BIT) {
            throw new IllegalArgumentException(
                    "Invalid revision part in SID \""
                            + sid
                            + "\": The revision must be an integer number between 0 and 255.");
        }
        int numberOfSubAuthorityParts = parts.length - 3;
        long authority;
        try {
            authority = Long.parseLong(parts[2]);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    "Invalid authority part in SID \""
                            + sid
                            + "\": The authority must be an integer number between 0 and 281474976710655.");
        }
        if (authority < 0 || authority > MASK_48_BIT) {
            throw new IllegalArgumentException(
                    "Invalid authority part in SID \""
                            + sid
                            + "\": The authority must be an integer number between 0 and 281474976710655.");
        }
        int[] subAuthority = new int[numberOfSubAuthorityParts];
        for (int i = 0; i < numberOfSubAuthorityParts; i++) {
            long subAuthorityPart;
            try {
                subAuthorityPart = Long.parseLong(parts[3 + i]);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException(
                        "Invalid sub-authority part in SID \""
                                + sid
                                + "\": The sub-authority parts must be integer numbers between 0 and 4294967295.");
            }
            if (subAuthorityPart < 0 || subAuthorityPart > MASK_32_BIT) {
                throw new IllegalArgumentException(
                        "Invalid sub-authority part in SID \""
                                + sid
                                + "\": The sub-authority parts must be integer numbers between 0 and 4294967295.");
            }
            subAuthority[i] = (int) subAuthorityPart;
        }
        byte[] bytes = new byte[8 + numberOfSubAuthorityParts * 4];
        // We have to write the authority first, otherwise it would overwrite
        // the revision and length bytes.
        ByteBuffer.wrap(bytes).putLong(authority);
        bytes[0] = (byte) revision;
        bytes[1] = (byte) numberOfSubAuthorityParts;
        ByteBuffer.wrap(bytes, 8, bytes.length - 8)
                .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().put(subAuthority);
        return bytes;
    }

}

The solution suggested by ho1 (using the Advapi32Util) class has two limitations:

  1. It needes the JNA library.
  2. It only works when running on the Windows platform, because it uses a Windows-API.

Therefore, I have written a class that is pure Java, has no external dependencies and will work on all platforms. This class can convert security identifiers from their binary to their textual representation and vice-versa.

If you are using Spring-LDAP, you can also use the methods provided by the LdapUtils class, however those methods do not peform any checks on the format of the SID and thus might produce incorrect results or unexpected exceptions.

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class SidConverter {

    private final static int MASK_8_BIT = 0xff;
    private final static long MASK_32_BIT = 0xffffffffL;
    private final static long MASK_48_BIT = 0xffffffffffffL;

    public static String bytesToString(byte[] bytes) {
        if (bytes.length < 8) {
            throw new IllegalArgumentException(
                    "Binary SID representation must have at least 8 bytes but passed byte array has only "
                            + bytes.length + " bytes.");
        }
        // The revision number is an unsigned 8-bit unsigned integer.
        int revision = bytes[0] & MASK_8_BIT;
        // The number of sub-authority parts is specified as an 8-bit unsigned
        // integer.
        int numberOfSubAuthorityParts = bytes[1] & MASK_8_BIT;
        if (bytes.length != 8 + numberOfSubAuthorityParts * 4) {
            throw new IllegalArgumentException(
                    "According to byte 1 of the SID it total length should be "
                            + (8 + 4 * numberOfSubAuthorityParts)
                            + " bytes, however its actual length is "
                            + bytes.length + " bytes.");
        }
        // The authority is a 48-bit unsigned integer stored in big-endian
        // format.
        long authority = ByteBuffer.wrap(bytes).getLong() & MASK_48_BIT;
        // The sub-authority consists of up to 255 32-bit unsigned integers in
        // little-endian format. The number of integers is specified by
        // numberOfSubAuthorityParts.
        int[] subAuthority = new int[numberOfSubAuthorityParts];
        ByteBuffer.wrap(bytes, 8, bytes.length - 8)
                .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().put(subAuthority);
        StringBuilder sb = new StringBuilder();
        sb.append("S-");
        sb.append(revision);
        sb.append("-");
        sb.append(authority);
        for (int subAuthorityPart : subAuthority) {
            sb.append("-");
            sb.append(subAuthorityPart & MASK_32_BIT);
        }
        return sb.toString();
    }

    public static byte[] stringToBytes(String sid) {
        if (!sid.startsWith("S-") && !sid.startsWith("s-")) {
            throw new IllegalArgumentException("Invalid SID \"" + sid
                    + "\": A valid SID must start with \"S-\".");
        }
        String[] parts = sid.split("-");
        if (parts.length < 3) {
            throw new IllegalArgumentException("Invalid SID \"" + sid
                    + "\": A valid SID must have at least two dashes.");
        }
        if (parts.length > MASK_8_BIT + 3) {
            throw new IllegalArgumentException("Invalid SID \"" + sid
                    + "\": A valid SID must not have more than 257 dashes.");
        }
        int revision;
        try {
            revision = Integer.parseInt(parts[1]);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    "Invalid revision part in SID \""
                            + sid
                            + "\": The revision must be an integer number between 0 and 255.");
        }
        if (revision < 0 || revision > MASK_8_BIT) {
            throw new IllegalArgumentException(
                    "Invalid revision part in SID \""
                            + sid
                            + "\": The revision must be an integer number between 0 and 255.");
        }
        int numberOfSubAuthorityParts = parts.length - 3;
        long authority;
        try {
            authority = Long.parseLong(parts[2]);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    "Invalid authority part in SID \""
                            + sid
                            + "\": The authority must be an integer number between 0 and 281474976710655.");
        }
        if (authority < 0 || authority > MASK_48_BIT) {
            throw new IllegalArgumentException(
                    "Invalid authority part in SID \""
                            + sid
                            + "\": The authority must be an integer number between 0 and 281474976710655.");
        }
        int[] subAuthority = new int[numberOfSubAuthorityParts];
        for (int i = 0; i < numberOfSubAuthorityParts; i++) {
            long subAuthorityPart;
            try {
                subAuthorityPart = Long.parseLong(parts[3 + i]);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException(
                        "Invalid sub-authority part in SID \""
                                + sid
                                + "\": The sub-authority parts must be integer numbers between 0 and 4294967295.");
            }
            if (subAuthorityPart < 0 || subAuthorityPart > MASK_32_BIT) {
                throw new IllegalArgumentException(
                        "Invalid sub-authority part in SID \""
                                + sid
                                + "\": The sub-authority parts must be integer numbers between 0 and 4294967295.");
            }
            subAuthority[i] = (int) subAuthorityPart;
        }
        byte[] bytes = new byte[8 + numberOfSubAuthorityParts * 4];
        // We have to write the authority first, otherwise it would overwrite
        // the revision and length bytes.
        ByteBuffer.wrap(bytes).putLong(authority);
        bytes[0] = (byte) revision;
        bytes[1] = (byte) numberOfSubAuthorityParts;
        ByteBuffer.wrap(bytes, 8, bytes.length - 8)
                .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().put(subAuthority);
        return bytes;
    }

}
梦太阳 2024-12-07 09:30:32

来自 http://miromannino.com/blog/convert- a-sid-to-string-with-java/

public static String convertSidToStringSid(byte[] sid) {
    int offset, size;

    // sid[0] is the Revision, we allow only version 1, because it's the
    // only that exists right now.
    if (sid[0] != 1)
        throw new IllegalArgumentException("SID revision must be 1");

    StringBuilder stringSidBuilder = new StringBuilder("S-1-");

    // The next byte specifies the numbers of sub authorities (number of
    // dashes minus two)
    int subAuthorityCount = sid[1] & 0xFF;

    // IdentifierAuthority (6 bytes starting from the second) (big endian)
    long identifierAuthority = 0;
    offset = 2;
    size = 6;
    for (int i = 0; i < size; i++) {
        identifierAuthority |= (long) (sid[offset + i] & 0xFF) << (8 * (size - 1 - i));
        // The & 0xFF is necessary because byte is signed in Java
    }
    if (identifierAuthority < Math.pow(2, 32)) {
        stringSidBuilder.append(Long.toString(identifierAuthority));
    } else {
        stringSidBuilder.append("0x").append(
                Long.toHexString(identifierAuthority).toUpperCase());
    }

    // Iterate all the SubAuthority (little-endian)
    offset = 8;
    size = 4; // 32-bits (4 bytes) for each SubAuthority
    for (int i = 0; i < subAuthorityCount; i++, offset += size) {
        long subAuthority = 0;
        for (int j = 0; j < size; j++) {
            subAuthority |= (long) (sid[offset + j] & 0xFF) << (8 * j);
            // The & 0xFF is necessary because byte is signed in Java
        }
        stringSidBuilder.append("-").append(subAuthority);
    }

    return stringSidBuilder.toString();
}

From http://miromannino.com/blog/convert-a-sid-to-string-with-java/

public static String convertSidToStringSid(byte[] sid) {
    int offset, size;

    // sid[0] is the Revision, we allow only version 1, because it's the
    // only that exists right now.
    if (sid[0] != 1)
        throw new IllegalArgumentException("SID revision must be 1");

    StringBuilder stringSidBuilder = new StringBuilder("S-1-");

    // The next byte specifies the numbers of sub authorities (number of
    // dashes minus two)
    int subAuthorityCount = sid[1] & 0xFF;

    // IdentifierAuthority (6 bytes starting from the second) (big endian)
    long identifierAuthority = 0;
    offset = 2;
    size = 6;
    for (int i = 0; i < size; i++) {
        identifierAuthority |= (long) (sid[offset + i] & 0xFF) << (8 * (size - 1 - i));
        // The & 0xFF is necessary because byte is signed in Java
    }
    if (identifierAuthority < Math.pow(2, 32)) {
        stringSidBuilder.append(Long.toString(identifierAuthority));
    } else {
        stringSidBuilder.append("0x").append(
                Long.toHexString(identifierAuthority).toUpperCase());
    }

    // Iterate all the SubAuthority (little-endian)
    offset = 8;
    size = 4; // 32-bits (4 bytes) for each SubAuthority
    for (int i = 0; i < subAuthorityCount; i++, offset += size) {
        long subAuthority = 0;
        for (int j = 0; j < size; j++) {
            subAuthority |= (long) (sid[offset + j] & 0xFF) << (8 * j);
            // The & 0xFF is necessary because byte is signed in Java
        }
        stringSidBuilder.append("-").append(subAuthority);
    }

    return stringSidBuilder.toString();
}
终止放荡 2024-12-07 09:30:32

使用来自InPlaceMsAdObjectSidValueEditor.java :(

protected String convertToString( byte[] bytes )
{
    /*
     * The binary data structure, from http://msdn.microsoft.com/en-us/library/cc230371(PROT.10).aspx:
     *   byte[0] - Revision (1 byte): An 8-bit unsigned integer that specifies the revision level of the SID structure. This value MUST be set to 0x01.
     *   byte[1] - SubAuthorityCount (1 byte): An 8-bit unsigned integer that specifies the number of elements in the SubAuthority array. The maximum number of elements allowed is 15.
     *   byte[2-7] - IdentifierAuthority (6 bytes): A SID_IDENTIFIER_AUTHORITY structure that contains information, which indicates the authority under which the SID was created. It describes the entity that created the SID and manages the account.
     *               Six element arrays of 8-bit unsigned integers that specify the top-level authority 
     *               big-endian!
     *   and then - SubAuthority (variable): A variable length array of unsigned 32-bit integers that uniquely identifies a principal relative to the IdentifierAuthority. Its length is determined by SubAuthorityCount. 
     *              little-endian!
     */

    if ( bytes == null || bytes.length < 8 )
    {
        return Messages.getString( "InPlaceMsAdObjectSidValueEditor.InvalidSid" ); //$NON-NLS-1$
    }

    char[] hex = Hex.encodeHex( bytes );
    StringBuffer sb = new StringBuffer();

    // start with 'S'
    sb.append( 'S' );

    // revision
    int revision = Integer.parseInt( new String( hex, 0, 2 ), 16 );
    sb.append( '-' );
    sb.append( revision );

    // get count
    int count = Integer.parseInt( new String( hex, 2, 2 ), 16 );

    // check length
    if ( bytes.length != ( 8 + count * 4 ) )
    {
        return Messages.getString( "InPlaceMsAdObjectSidValueEditor.InvalidSid" ); //$NON-NLS-1$
    }

    // get authority, big-endian
    long authority = Long.parseLong( new String( hex, 4, 12 ), 16 );
    sb.append( '-' );
    sb.append( authority );

    // sub-authorities, little-endian
    for ( int i = 0; i < count; i++ )
    {
        StringBuffer rid = new StringBuffer();
        for ( int k = 3; k >= 0; k-- )
        {
            rid.append( hex[16 + ( i * 8 ) + ( k * 2 )] );
            rid.append( hex[16 + ( i * 8 ) + ( k * 2 ) + 1] );
        }

        long subAuthority = Long.parseLong( rid.toString(), 16 );
        sb.append( '-' );
        sb.append( subAuthority );
    }

    return sb.toString();
}

来自 Apache Directory Studio)

use convertToString from InPlaceMsAdObjectSidValueEditor.java :

protected String convertToString( byte[] bytes )
{
    /*
     * The binary data structure, from http://msdn.microsoft.com/en-us/library/cc230371(PROT.10).aspx:
     *   byte[0] - Revision (1 byte): An 8-bit unsigned integer that specifies the revision level of the SID structure. This value MUST be set to 0x01.
     *   byte[1] - SubAuthorityCount (1 byte): An 8-bit unsigned integer that specifies the number of elements in the SubAuthority array. The maximum number of elements allowed is 15.
     *   byte[2-7] - IdentifierAuthority (6 bytes): A SID_IDENTIFIER_AUTHORITY structure that contains information, which indicates the authority under which the SID was created. It describes the entity that created the SID and manages the account.
     *               Six element arrays of 8-bit unsigned integers that specify the top-level authority 
     *               big-endian!
     *   and then - SubAuthority (variable): A variable length array of unsigned 32-bit integers that uniquely identifies a principal relative to the IdentifierAuthority. Its length is determined by SubAuthorityCount. 
     *              little-endian!
     */

    if ( bytes == null || bytes.length < 8 )
    {
        return Messages.getString( "InPlaceMsAdObjectSidValueEditor.InvalidSid" ); //$NON-NLS-1$
    }

    char[] hex = Hex.encodeHex( bytes );
    StringBuffer sb = new StringBuffer();

    // start with 'S'
    sb.append( 'S' );

    // revision
    int revision = Integer.parseInt( new String( hex, 0, 2 ), 16 );
    sb.append( '-' );
    sb.append( revision );

    // get count
    int count = Integer.parseInt( new String( hex, 2, 2 ), 16 );

    // check length
    if ( bytes.length != ( 8 + count * 4 ) )
    {
        return Messages.getString( "InPlaceMsAdObjectSidValueEditor.InvalidSid" ); //$NON-NLS-1$
    }

    // get authority, big-endian
    long authority = Long.parseLong( new String( hex, 4, 12 ), 16 );
    sb.append( '-' );
    sb.append( authority );

    // sub-authorities, little-endian
    for ( int i = 0; i < count; i++ )
    {
        StringBuffer rid = new StringBuffer();
        for ( int k = 3; k >= 0; k-- )
        {
            rid.append( hex[16 + ( i * 8 ) + ( k * 2 )] );
            rid.append( hex[16 + ( i * 8 ) + ( k * 2 ) + 1] );
        }

        long subAuthority = Long.parseLong( rid.toString(), 16 );
        sb.append( '-' );
        sb.append( subAuthority );
    }

    return sb.toString();
}

(from Apache Directory Studio)

明明#如月 2024-12-07 09:30:32

不使用 JNA 的示例

这里有一些不错的紧凑代码,用于在不使用 JNA 的情况下转换 SID。它甚至内置了一些“错误检查”功能,如果出现问题,则返回 NULL、EMPTY 或零长度数组。

对于 SID 到字符串:

/**
 * Converts Windows SID to a String. NULL input returns NULL.
 * Invalid byte array returns EMPTY.
 * @param sid SID as byte array.
 * @return SID as String.
 */
public static String convertSidToStr(byte[] sid) {
    if (sid==null) return null;
    if (sid.length<8 || sid.length % 4 != 0) return "";
    StringBuilder sb = new StringBuilder();
    sb.append("S-").append(sid[0]);
    int c = sid[1]; // Init with Subauthority Count.
    ByteBuffer bb = ByteBuffer.wrap(sid);
    // bb.order(ByteOrder.BIG_ENDIAN); // Not needed, default big endian.
    sb.append("-").append((long)bb.getLong() & 0XFFFFFFFFFFFFL);
    bb.order(ByteOrder.LITTLE_ENDIAN); // Now switch.
    for (int i=0; i<c; i++) { // Create Subauthorities.
        sb.append("-").append((long)bb.getInt() & 0xFFFFFFFFL);
    }        
    return sb.toString();    
}

对于字符串到 SID:

/**
 * Converts Windows SID String to byte array. NULL input returns NULL.
 * Invalid String returns zero-length byte array.
 * @param sid SID as String.
 * @return SID as byte array.
 */
public static byte[] convertStrToSid(String sid) {
    if (sid==null) return null;
    if (!sid.matches("^[sS]-\\d-\\d{1,13})"
            + "(?:-\\d{1,10})*$")) return new byte[0];
    String[] ss = sid.split("-");
    int c=ss.length-3; // Init with Subauthority Count.
    byte[] b=new byte[2+6+(c*4)];
    ByteBuffer bb = ByteBuffer.wrap(b);
    // bb.order(ByteOrder.BIG_ENDIAN); // Not needed, default big endian.
    bb.putLong(Long.parseLong(ss[2]));
    // Overlay bytes 0 and 1 with Revision and Identifier Authority.
    b[0]=(byte)Short.parseShort(ss[1]);
    b[1]=(byte)c;
    bb.order(ByteOrder.LITTLE_ENDIAN); // Now switch.
    for (int i=0; i<c; i++) { // Create Subauthorities.
        bb.putInt((int)Long.parseLong(ss[i+3]));
    }
    return b;    
}

有关参考,请参阅 TechNet 的 安全标识符结构

Example Without JNA

Here's some nice compact code for converting SIDs without using JNA. It even has some "error checking" built in by returning NULL, EMPTY, or a zero-length array if something isn't quite right.

For SID to String:

/**
 * Converts Windows SID to a String. NULL input returns NULL.
 * Invalid byte array returns EMPTY.
 * @param sid SID as byte array.
 * @return SID as String.
 */
public static String convertSidToStr(byte[] sid) {
    if (sid==null) return null;
    if (sid.length<8 || sid.length % 4 != 0) return "";
    StringBuilder sb = new StringBuilder();
    sb.append("S-").append(sid[0]);
    int c = sid[1]; // Init with Subauthority Count.
    ByteBuffer bb = ByteBuffer.wrap(sid);
    // bb.order(ByteOrder.BIG_ENDIAN); // Not needed, default big endian.
    sb.append("-").append((long)bb.getLong() & 0XFFFFFFFFFFFFL);
    bb.order(ByteOrder.LITTLE_ENDIAN); // Now switch.
    for (int i=0; i<c; i++) { // Create Subauthorities.
        sb.append("-").append((long)bb.getInt() & 0xFFFFFFFFL);
    }        
    return sb.toString();    
}

For String to SID:

/**
 * Converts Windows SID String to byte array. NULL input returns NULL.
 * Invalid String returns zero-length byte array.
 * @param sid SID as String.
 * @return SID as byte array.
 */
public static byte[] convertStrToSid(String sid) {
    if (sid==null) return null;
    if (!sid.matches("^[sS]-\\d-\\d{1,13})"
            + "(?:-\\d{1,10})*$")) return new byte[0];
    String[] ss = sid.split("-");
    int c=ss.length-3; // Init with Subauthority Count.
    byte[] b=new byte[2+6+(c*4)];
    ByteBuffer bb = ByteBuffer.wrap(b);
    // bb.order(ByteOrder.BIG_ENDIAN); // Not needed, default big endian.
    bb.putLong(Long.parseLong(ss[2]));
    // Overlay bytes 0 and 1 with Revision and Identifier Authority.
    b[0]=(byte)Short.parseShort(ss[1]);
    b[1]=(byte)c;
    bb.order(ByteOrder.LITTLE_ENDIAN); // Now switch.
    for (int i=0; i<c; i++) { // Create Subauthorities.
        bb.putInt((int)Long.parseLong(ss[i+3]));
    }
    return b;    
}

For reference, see TechNet's Security Identifier Structure.

终陌 2024-12-07 09:30:32

现有的解决方案都没有帮助我。但是 spring-ldap 可以正确地做到这一点:

val e:SearchResultEntry  = ldapConnection....
val objectSidBytes = getAttributeValueBytes("ObjectSid")
val sid = LdapUtils.convertBinarySidToString(objectSidBytes)

依赖项是

implementation("org.springframework.ldap:spring-ldap-core:3.1.1")

Neither of existing solutions helped me. But spring-ldap can do it properly:

val e:SearchResultEntry  = ldapConnection....
val objectSidBytes = getAttributeValueBytes("ObjectSid")
val sid = LdapUtils.convertBinarySidToString(objectSidBytes)

The dependency is

implementation("org.springframework.ldap:spring-ldap-core:3.1.1")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文