- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一些软件使用 RSA 身份验证代理的文档化 API。这是一种在域中的客户端计算机上作为服务运行的产品,并通过与集中安装的“RSA 身份验证管理器”进行通信来在本地对用户进行身份验证。
身份验证代理的 API 在此处公开记录:Authentication Agent API 8.1.1 for C Developers Guide .但是,文档似乎不正确,而且我无权访问 RSA 头文件——它们不是公开的;只有 PDF 文档可供下载,无需向 RSA 支付 $$。如果这里有人可以访问最新的头文件,您能帮我确认文档是否已过时吗?
API 文档中给出的函数签名似乎不正确 - 事实上,我绝对相信它们在 x64 机器上是错误的。例如,最新的 PDF 文档显示如下:
int WINAPI AceSetUserData(SDI_HANDLE hdl, unsigned int userData)
int WINAPI AceGetUserData(SDI_HANDLE hdl, unsigned int *pUserData)
文档多次指出“userData”值是一个 32 位数量,例如在 AceInit
、AceSetUserData
和 AceGetUserData 的文档中
。 AceGetUserData
文档的相关摘录:
This function is synchronous and the caller must supply, as the second argument, a pointer to a 32-bit storage area (that is, an unsigned int) into which to copy the user data value.
这显然是错误的 - 从一些实验来看,如果你传入一个指向填充了 0xff 的缓冲区中心的指针,AceGetUserData
肯定写出一个 64-位值,而不是 32 位数量。
我的aceclnt.dll
版本是8.1.3.563;相应的文档标记为“Authentication Agent API 8.1 SP1”,这对应于 Authentication Agent 本身的版本 7.3.1。
给出了完整的测试代码,即使它与问题根本无关......如果其他人运行测试代码对我来说没有用(我知道它的作用!),我需要的是可以访问的人可以确认函数签名的RSA头文件。
#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef WIN32
#include <Windows.h>
#include <tchar.h>
#define SDAPI WINAPI
#else
#define SDAPI
#endif
typedef int SDI_HANDLE;
typedef uint32_t SD_BOOL;
typedef void (SDAPI* AceCallback)(SDI_HANDLE);
#define ACE_SUCCESS 1
#define ACE_PROCESSING 150
typedef SD_BOOL (SDAPI* AceInitializeEx_proto)(const char*, char*, uint32_t);
typedef int (SDAPI* AceInit_proto)(SDI_HANDLE*, void*, AceCallback);
typedef int (SDAPI* AceClose_proto)(SDI_HANDLE, AceCallback);
typedef int (SDAPI* AceGetUserData_proto)(SDI_HANDLE, void*);
typedef int (SDAPI* AceSetUserData_proto)(SDI_HANDLE, void*);
struct Api {
AceInitializeEx_proto AceInitializeEx;
AceInit_proto AceInit;
AceClose_proto AceClose;
AceGetUserData_proto AceGetUserData;
AceSetUserData_proto AceSetUserData;
} api;
static void api_init(struct Api* api) {
// All error-checking stripped...
HMODULE dll = LoadLibrary(_T("aceclnt.dll")); // leak this for the demo
api->AceInitializeEx = (AceInitializeEx_proto)GetProcAddress(dll, "AceInitializeEx");
api->AceInit = (AceInit_proto)GetProcAddress(dll, "AceInit");
api->AceClose = (AceClose_proto)GetProcAddress(dll, "AceClose");
api->AceGetUserData = (AceGetUserData_proto)GetProcAddress(dll, "AceGetUserData");
api->AceSetUserData = (AceSetUserData_proto)GetProcAddress(dll, "AceSetUserData");
int success = api->AceInitializeEx("C:\\my\\conf\\directory", 0, 0);
assert(success);
}
static void demoFunction(SDI_HANDLE handle) {
union {
unsigned char testBuffer[sizeof(void *) * 3];
void *forceAlignment;
} u;
memset(u.testBuffer, 0xA5, sizeof u.testBuffer);
int err = api.AceGetUserData(handle, (void*)(u.testBuffer + sizeof(void*)));
assert(err == ACE_SUCCESS);
fputs("DEBUG: testBuffer =", stderr);
for (size_t i = 0; i < sizeof(u.testBuffer); i++) {
if (i % 4 == 0)
putc(' ', stderr);
fprintf(stderr, "%02x", u.testBuffer[i]);
}
fputc('\n', stderr);
// Prints:
// DEBUG: testBuffer = a5a5a5a5 a5a5a5a5 00000000 00000000 a5a5a5a5 a5a5a5a5
// According to the docs, this should only write out a 32-bit value
}
static void SDAPI demoCallback(SDI_HANDLE h) {
fprintf(stderr, "Callback invoked, handle = %p\n", (void*)h);
}
int main(int argc, const char** argv)
{
api_init(&api);
SDI_HANDLE h;
int err = api.AceInit(&h, /* contentious argument */ 0, &demoCallback);
assert(err == ACE_PROCESSING);
demoFunction(h);
api.AceClose(h, 0);
return 0;
}
最佳答案
当您从文档中复制函数/类型定义时,您基本上没有也永远不会对您正在使用的 .dll 版本有正确的定义,并且可能总是以崩溃或崩溃告终更糟糕的是,未定义的行为。
你可以做的是调试相应的.dll:
您运行 Visual Studio 吗?我记得 VS 可以在 Debug模式下进入函数调用并显示程序集,但不确定今天如何。但是任何反汇编程序都应该可以解决问题。截至x64 ABI register rcx
获取第一个参数,rdx
第二个。如果该函数在内部使用 32 位寄存器名称或清除高 32 位,则您可以假设一个 32 位整数。如果它使用它来加载地址(例如 lea
指令),您可以假设一个指针。但正如您所见,这可能不是您想走的路...
那你还剩下什么?
您链接的文档说明了 32 位和 64 位库 - 取决于您使用的平台。我猜你使用的是 64 位库,RSA 没有更新这个库的文档,但在某些时候开发人员需要将库升级到 64 位。
所以请这样想:如果您是 API 开发人员,什么可以迁移到 64 位,什么不能。例如。无法触及需要跨 32/64 实现工作的所有内容(通过网络发送或存储和共享在磁盘上的内容)。但是实例本地的所有内容都可以迁移。由于 userData
似乎是一个运行时的东西,支持平台提供的任何东西都是有意义的:unsigned long
在 64 位上和 unsigned int
在 32 位上.
您已经知道 userData
必须是 64 位的。但不是因为该函数写出一个 64 位整数,而是因为该函数看到一个 64 位值开始。由于整数是按值传递的(我猜一般情况下,但肯定是在 WINAPI 中),如果函数是 32 位数据类型,则该函数绝对不可能看到完整的 64 位值。因此,API 开发人员很可能将数据类型更改为 unsigned long
(无论如何更改为 64 位类型)。
PS:如果您最终将指针放入 userData,请将指针转换为 uintptr_t
并存储/读取该类型。
关于c - RSA Authentication Agent API 文档中的函数签名是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42560402/
我目前正在使用 Crypto++ 为数据块生成签名。我希望签名是 20 个字节(SHA 1 Hash),因为我的理解是签名只是一个加密的哈希。但是当检查 maxsignaturelength 和 si
我不是加密专家,所以我对这些事情的了解接近于零。我必须与使用 RSA 加密的系统进行互操作。使用他们的 key 时,我遇到了为相同的输入/ key 获取不同密码的问题。图书馆是https://code
我想利用 postman 来测试需要使用 RSA 加密对输入字段之一进行加密的 REST API。 我看到 postman 通过 require('crypto-js') 提供了功能使用 AES 加密
我正在尝试在我的 (Java) 应用程序中实现一个(简化的)类似 RSA 的验证过程。客户端发送一个请求(数据+私钥签名),服务器要么拒绝他的请求,要么处理它——取决于签名的有效性。 但是我不明白验证
我正在尝试在我的 (Java) 应用程序中实现一个(简化的)类似 RSA 的验证过程。客户端发送一个请求(数据+私钥签名),服务器要么拒绝他的请求,要么处理它——取决于签名的有效性。 但是我不明白验证
下面是我想要做的最小、完整且可验证的示例。 基本上我想实现一个集成一些 CUDA 代码的 OpenSSL RSA 引擎。 CUDA 部分应该执行模幂运算,但在本例中并不重要,因此我只是按顺序使用了 B
是否有任何非常简单的跨平台 C++ 库可以进行不对称加密?不需要高效,只要工作。我想它可能只是 .h 文件中的 3-4 个函数,它们可以执行任意精度的数学运算,仅此而已。 我相信在这里使用 OpenS
我使用以下命令创建了私钥和公钥, openssl genrsa -out privatekey.pem 1024 openssl req -new -x509 -key privatekey.pem
我在 .net 环境(所有版本)中工作并使用 vb.net。我想根据密码生成 RSA 公钥和私钥。 我对 RSA 算法的理解仅限于使用 .net 提供的类,即 System.Security.Cryp
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我有 ssh-keygen 生成的 id_rsa.pub key 。 如何以编程方式将 id_rsa.pub 文件转换为 RSA DER 格式的 key ? 最佳答案 如果使用 ssh-keygen
我在 JWT(JSON Web Token)方案的帮助下实现了一个登录系统。基本上,在用户登录/登录后,服务器对 JWT 进行签名并将其传递给客户端。 然后客户端在每个请求中返回 token ,服务器
我使用的是 WAS 6.1,我的服务器过去可以正常启动,但突然间无法正常工作.. 当我尝试在我的本地 RSA 中启动我的服务器时。我收到以下错误 我已经重新启动了系统,RSA,杀死了所有 Java 进
我正在开发一个支付网关,他们有一个正在运行的 Java 演示,但我想用 php 来实现它。 支付网关使用 3DES 和随机生成的 key 来加密有效负载。该 key 使用支付网关的公钥通过 RSA 进
这是此处未回答问题的副本:Using an RSA Public Key to decrypt a string that was encrypted using RSA Private Key 您可
我一直无法将 RSA 加密字节编码为字符串,然后在另一端(远程主机)将它们恢复为字节,另一端抛出“错误数据”异常。 我试过谷歌,没有运气。 到目前为止我的代码: 客户: array^Test=Enco
我需要一些帮助来解决我的问题。 问题:我想用 Android 平台的公共(public) RSA key 加密一个数字 (A),然后用私钥在 PHP 服务器上解密它。在每个平台上,我都可以加密和解密数
当我尝试将参数传递给函数时出现以下错误。 error[E0243]: wrong number of type arguments: expected 1, found 0 --> src/mai
我尝试将公共(public) RSA key 加载到我的程序中。我在 C 中使用 openssl 库。 key 在 header crypt.h 文件中定义: #define PUBLIC_KEY
Bouncy CaSTLe 加密库中有两种不同的密码可以传递给 PKCS1Encoding:NativeRSAEngine 和 RSAEngine。这两个变体之间有区别吗? 编辑: 正如 Maarte
我是一名优秀的程序员,十分优秀!