gpt4 book ai didi

java - 通过 void** 参数作为 char[] 与 JNA 获取函数结果

转载 作者:太空宇宙 更新时间:2023-11-03 23:41:40 24 4
gpt4 key购买 nike

TL;DR:我将什么 JNA 类型用于 void** 指针(实际上是一个 char**),以及如何访问结果从中?

我正在尝试使用 this C function 从 Java 中的 macOS Keychain 获取密码:

OSStatus SecKeychainFindGenericPassword(CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char *serviceName,
UInt32 accountNameLength,
const char *accountName,
UInt32 *passwordLength,
void * _Nullable *passwordData,
SecKeychainItemRef _Nullable *itemRef);

( Usage example. )

问题是,我不确定如何处理 passwordData 参数。我设法从 C 调用它(见帖子底部)。但是,在 Java 中,我得到了 passwordData 参数的不确定且不正确的结果。这是我从 Java 调用它的尝试:

import com.sun.jna.*;
import com.sun.jna.ptr.*;

public class JnaTest {

public interface Security extends Library {
int SecKeychainFindGenericPassword(
Object keychainOrArray,
int serviceNameLength,
String serviceName,
int accountNameLength,
String accountName,
IntByReference passwordLength,
// I've also tried char[][] and Pointer, which both give errors
PointerByReference passwordData,
Object itemRef);
}

public static void main(String[] args) {
Security sec = Native.loadLibrary("Security", Security.class);

PointerByReference pass = new PointerByReference();
IntByReference len = new IntByReference();
int rc = sec.SecKeychainFindGenericPassword(
null,
10, "SurfWriter",
10, "MyUserAcct",
len, pass,
null);

System.out.println(rc); // 0, good
System.out.println(len.getValue()); // 11, same as in C
// This prints Unicode characters nondeterministically; buffer overrun?
System.out.println(new String(pass.getValue().getCharArray(0, len.getValue())));
}

}

我能够编写这个 C 程序来做同样的事情,而且它工作正常,所以问题几乎肯定是在 JNA 中读取 passwordData:

#include <Security/Security.h>

int main() {
unsigned int len;
void* pass;
int rc = SecKeychainFindGenericPassword(
NULL,
10, "SurfWriter",
10, "MyUserAcct",
&len, &pass,
NULL);
printf("%d %s\n", len, pass);
}

最佳答案

事实证明,如果我这样做,它会起作用:

pass.getValue().getString(0);

它有效。完美。不幸的是,这不是一个完整的解决方案,因为出于安全原因我想避免将密码存储在 String 中。又玩了一些,我发现这行得通:

new String(pass.getValue().getByteArray(0, len.getValue()-4));

(-4 是因为 len 由于某种原因太大了 4;我在 安全文档中找不到任何关于此的内容。 h.) 我意识到它之前打印的“随机”密码在后半部分只是随机的,这让我得出一个结论:Java uses 16-bit chars internally ,所以我得到的每个字符实际上都是两个字符,而且我在必要时阅读了两倍。 Java 将 2 个 ASCII 字符视为一个 UTF-16 字符。 (JNA 不应该处理这个吗?)

关于java - 通过 void** 参数作为 char[] 与 JNA 获取函数结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43929390/

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