使用openssl使用公钥检查数据签名

时间:2016-05-19 20:44:22

标签: android c android-ndk openssl

我有一些签名数据(以signdata分隔,其签名[base64编码])应该由提供的公钥验证匹配。数据由外部函数提供,这些函数将数据存储在如下结构中。

typedef struct {
    char * signature;
    char * signedData;   // base64 encoded --> decoding required
} data;

我需要将其转换为适合openssl函数并假设某处有错误。它编译,但崩溃(SIGSEGV)。它是一个Android库,我使用的是NDK。有什么想法/提示吗?可能是某种转换问题?

// base64 function source:How do I base64 encode (decode) in C?

//根据http://fm4dd.com/openssl/manual-crypto/EVP_PKEY_verify.htm

检查签名
    size_t sdlen, siglen; 

    char *tmp = malloc(1000);
    char *signature = malloc(1000);
    char *signData = malloc(1000);

    sprintf(tmp, "%s", data.signature);
    signature = base64decode(&tmp, strlen(tmp));
    siglen = strlen(signature);

    sprintf(signData, "%s", data.signedData);
    sdlen = strlen(signData);


    EVP_PKEY_CTX *ctx = malloc(1000);
    unsigned char *md, *sig;

    char publickeybase64[] = "MIIBIjANBgkqhk.....";
    char *publickey = base64decode(&publickeybase64, strlen(publickeybase64));

    EVP_PKEY *verify_key = malloc(1000);
    sprintf((char *) verify_key, "%s", publickey);

    ctx = EVP_PKEY_CTX_new(verify_key, 0);

    if (!ctx) {
        printf("E1\n");
    }
    if (EVP_PKEY_verify_init(ctx) <= 0) {
        printf("E2\n");
    }
    if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
        printf("E3\n");
    }
    if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256() <= 0)) {
        printf("E4\n");
    }

    int ret = EVP_PKEY_verify(ctx, signature, siglen, signData, sdlen);

    printf("RESULTVERIFY %d \n", ret);

    /* ret == 1 indicates success, 0 verify failure and < 0 for some
     * other error.
     */

1 个答案:

答案 0 :(得分:0)

我不知道究竟是什么编码在“publickeybase64”中,但创建公钥的整个过程对我来说似乎有点奇怪。

首先,我会替换

EVP_PKEY *verify_key = malloc(1000);

类似

EVP_PKEY *verify_key = malloc(sizeof(EVP_PKEY));

或者,如果您使用最新版本的OpenSSL,

EVP_PKEY *verify_key = EVP_PKEY_new();

然后,您需要为verify_key设置RSA密钥。见https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_set1_RSA.html

因此,我认为您首先需要创建RSA密钥(https://www.openssl.org/docs/manmaster/crypto/RSA_new.html)并设置其模数和公共指数(请参阅https://www.openssl.org/docs/manmaster/crypto/RSA_set0_key.html)。