我正在使用RSA_verify()函数来验证我使用openssl程序(通过控制台)签名的SHA。 RSA_verify()总是返回一个非成功的验证,所以我认为我发送的参数不正确。
以下控制台命令在Linux Ubuntu中使用OpenSSL 0.9.8k运行。
据我记得,使用OpenSSL 1.0.1 ... c为Android编译了C函数。它肯定是1.0.1(我们正在更新它以避免Heartbleed问题)。
这就是我所做的......请原谅任何错误,因为我自己也在学习。
生成私钥
openssl genrsa -out private.key 2048
从私钥中提取公钥
openssl rsa -in private.key -out public.key -outform PEM -pubout
从名为permissions的文件计算SHA,然后使用private.key对其进行签名,输出将为SHA但具有RSA加密(permissions.sign)
openssl dgst -sha256 -sign private.key -out permissions.sign permissions
根据权限文件验证收到的SHA签名(它在Ubuntu控制台中是否成功)
openssl dgst -sha256 -verify public.key -signature permissions.sign permissions
我将权限文件,permissions.sign文件和public.key文件复制到Android中的文件系统。
我验证了permissions.sign是使用权限和匹配的private.key创建的...所有这些都与我的public.key一起使用(我没有Android中的私钥)。< / p>
这是C函数。
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
...
/* Initialize the public key */
RSA *pub_key = RSA_new();
if(NULL == pub_key)
{
ANDROID_LOGE("RSA_new failed");
result = 0;
}
else
{
FILE* fp = fopen(public_key, "r");
if(NULL == fp)
{
ANDROID_LOGE_P("fopen [%s] failed", public_key);
result = 0;
}
else
{
/* Read it from the passed path */
if(PEM_read_RSA_PUBKEY(fp, &pub_key, NULL, NULL) == NULL)
{
ANDROID_LOGE_P("[%s] can't be read", public_key);
result = 0;
fclose(fp);
}
else
{
/* Verify the file and its SHA with the public key */
int verified = RSA_verify(
NID_sha256,
file, /* message digest (message to validate) */
file_size, /* message size */
sign, /* signature (signed SHA) */
sign_size, /* signature size */
pub_key);
ANDROID_LOGD("NID_sha256");
if(verified)
{
result = 1;
ANDROID_LOGD_P("[%s] is valid", file_to_verify);
}
else
{
ANDROID_LOGE_P("[%s] is NOT valid", file_to_verify);
}
fclose(fp);
}
RSA_free(pub_key);
}
}
所以问题是,它是否正确:
使用我使用的命令生成密钥,
签署权限文件(生成permissions.sign),
然后尝试使用PEM_read_RSA_PUBKEY()和RSA_verify()验证文件?
我用于签名过程的命令是否等同于我用于验证过程的C函数?
如果需要更多信息或我可以在哪里学习更多信息,请告诉我。
谢谢!
编辑:我在调用RSA_Verify()之后添加了一些错误打印:
ANDROID_LOGE_P(&#34; openssl:%s&#34;,ERR_reason_error_string(ERR_get_error()));
打印:
openssl:bad signature
仍在调查。
答案 0 :(得分:2)
我的公钥读取过程中有几个缺失的步骤。
生成私钥和公钥的正确命令如下:
生成私钥 “openssl genrsa -out private.key 2048”
从私钥中提取公钥(DER证书表单)(RSA_SHA_Verify()需要) “openssl req -outform DER -new -x509 -key private.key -out public.key -days 30000”
生成没有证书信息的公钥(只有“openssl dgst -sha1 -verify ...”需要) “openssl x509 -inform DER -in public.key -pubkey -noout&gt; public_no_cert.key”
使用私钥对文件进行签名 “openssl dgst -sha1 -sign private.key -out permissions.sign permissions”
使用公钥验证文件(无证书信息) “openssl dgst -sha1 -verify public_no_cert.key -signature permissions.sign permissions”
有关详细信息,请参阅OpenSSL.org上的文档。我需要一个持有公钥的X509 DER证书来验证带有RSA_verify()的签名SHA。
RSA_verify()的命令模式的等效性是:
openssl dgst -sha1 -verify public.key -signature permissions.sign permissions
有关代码来源,请参阅此链接: http://www.bmt-online.org/geekisms/RSA_verify
它不会乍一看,你必须调整它。按如下方式调用其中的函数:
result = sign_data(
input_file_buffer,
input_file_size,
private_key_buffer,
private_key_size,
(void**)&signature,
&signature_size);
result = verify_data(
input_file_buffer,
input_file_size,
signature_buffer,
signature_size,
public_key_buffer,
public_key_size);
一切都必须在RAM中,将它们作为指针传递。
签名函数需要指向指针(**)的指针将签名的SHA保存到其中。您可以稍后将其保存到文件中。
在Ubuntu openssl 0.9.8k下测试。
如果您发现缺少某些内容,请告知我们。谢谢你的阅读!
编辑:这是源代码的链接...... http://migsantiago.com/index.php/tutoriales/32-firma-y-valida-archivos-con-openssl