2014-01-14 121 views
4

我有我需要用来验证数字签名的RSA base64编码公钥。我不明白如何用公钥来初始化RSA。openssl初始化RSA公钥

我的代码看起来是这样的:

unsigned char *signature = ""; //signature string 
char *original = ""; // my original string 
unsigned char sha2HashDigest[SHA256_DIGEST_LENGTH]; 
SHA256(original, strlen(original), sha2HashDigest); 

char *key = "base64encodedKey"; 

RSA *r = RSA_new(); 
//SET RSA public key?! how? 

int result = RSA_verify(NID_sha256, sha2HashDigest, SHA256_DIGEST_LENGTH, 
      signature, strlen(signatrue), r); 
if (result != 1) // handle error 

注:我在的iOS应用程序这样做,但我认为这是无关紧要的问题。

更新:我最终使用vond建议的EVP。公钥是PEM格式的文​​件。这是我的代码:

FILE *fp = fopen([keyFilePath UTF8String], "r"); 
    if (!fp) return NO; 


    EVP_PKEY *pubKey = PEM_read_PUBKEY(fp,NULL,NULL,NULL); 
    EVP_MD_CTX  md_ctx; 
    EVP_MD_CTX_init(&md_ctx); 

    EVP_VerifyInit(&md_ctx, EVP_sha256()); 
    EVP_VerifyUpdate (&md_ctx, (unsigned char*)[msgData bytes], [msgData length]); 
    int err = EVP_VerifyFinal (&md_ctx, (unsigned char*) sigData, (unsigned int)[sigData length], pubKey); 
    EVP_PKEY_free (pubKey); 
+0

您是PEM格式的关键吗?如果是这样,[pem(3)](http://www.openssl.org/docs/crypto/pem.html#)与适当的内存BIO一起可能是你想要的。 – WhozCraig

+0

它只是base64字符串。我可以制作一个pem文件,但这不是不必要的复杂吗? – Maggie

回答

9

你可以尝试以下操作:

const char *pub_key_pem = ...; 

BIO *bio = BIO_new_mem_buf((void*)pub_key_pem, strlen(pub_key_pem)); 
RSA *rsa_pub = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); 

注:PEM_read_bio_RSAPublicKey()预计PKCS#1 PEM格式(与 “BEGIN/END RSA公共密钥” 划线在第一/最后一行);如果您拥有“BEGIN/END PUBLIC KEY”的PEM,则应该尝试使用PEM_read_bio_RSA_PUBKEY()。请参阅区别herehere的解释。

如果你没有任何在你的base64字符串,这些虚线的,你可能会发现更容易以base64字符串解码成二进制缓冲区,然后使用d2i_RSAPublicKey()d2i_RSA_PUBKEY()之一来从RSA*公钥它。

+0

就个人而言,如果可能的话,我宁愿将高级EVP界面添加到您现在尝试使用的界面。请参阅https://www.openssl.org/docs/crypto/EVP_SignInit.html – vond

+0

然后,我将如何使用EVP?据我所知,我没有用于签名验证的方法。 – Maggie

+0

使用EVP,您可能需要EVP_VerifyInit,EVP_VerifyUpdate和EVP_VerifyFinal,请参阅http://www.openssl.org/docs/crypto/EVP_VerifyInit.html中的API – vond