繁体   English   中英

生成RSA并保存在ASN.1 / DER中的分段错误?

[英]Segmentation fault with generating an RSA and saving in ASN.1/DER?

#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>

#define RSA_LEN 2048
#define RSA_FACTOR 65537

int genRSA2048(unsigned char **pub,unsigned int *pub_l,unsigned char **priv,unsigned int *priv_l){

    RSA *pRSA = NULL;
    pRSA = RSA_generate_key(RSA_LEN,RSA_FACTOR,NULL,NULL);

    if (pRSA){
        pub_l = malloc(sizeof(pub_l));
        *pub_l = i2d_RSAPublicKey(pRSA,pub);
        priv_l = malloc(sizeof(priv_l));
        *priv_l = i2d_RSAPrivateKey(pRSA,priv);
        return 0;
    } else {
        return 1;
    }
}

int main(){
    unsigned char *pub = NULL;
    unsigned int publ;
    unsigned char *priv = NULL;
    unsigned int privl;
    genRSA2048(&pub,&publ,&priv,&privl);


    RSA *privrsa = NULL;
    d2i_RSAPrivateKey(&privrsa,(const unsigned char **)&priv,privl);

    RSA *pubrsa = NULL;
    d2i_RSAPublicKey(&pubrsa,(const unsigned char **)&pub,publ);

    unsigned char * data ="01234567890123456789012345678912";
    unsigned char encrypted[256];
    unsigned char decrypted[32];

    int len = RSA_private_encrypt(32,data,encrypted,privrsa,RSA_PKCS1_PADDING);
    RSA_public_decrypt(len,encrypted,decrypted,pubrsa,RSA_PKCS1_PADDING);
}

我试图通过与gdb进行检查来发现错误,但是对于CI来说,它还很陌生,没有任何线索可以告诉我发生了什么,但是我相信这是一个分配问题,但是根据d2i_RSAPrivateKey和类似的说法,应该自己分配空间。

任何帮助将不胜感激。

编译为cc foo.c -lcrypto

这是此问题的跟进:

使用OpenSSL生成RSA公钥/私钥?

正如我所引用的那样,我在注释中使用了@WhozCraig示例,即使在非常不同的地方也可以找到它,这对您有很大帮助。

http://coliru.stacked-crooked.com/a/ae64a70076436165

pub_l = malloc(sizeof(pub_l)); 根本不需要。 priv_l = malloc(sizeof(priv_l));也不priv_l = malloc(sizeof(priv_l)); 将它们都从功能中删除。

您应该填充自己的参数。 取而代之的是,您扔掉了呼叫者提供的地址来填充,并且(a)填充了自己的地址,然后(b)泄漏了刚分配的内存。

结果是调用者的privlpubl未被修改,因此返回给RSA的解码功能不正常,因为这两个值都是不确定的。

 pRSA = RSA_generate_key(RSA_LEN,RSA_FACTOR,NULL,NULL); 

我认为这是错误的。 我知道您应该使用RSA_generate_key_ex ,并且我认为它需要BIGNUM而不是整数。 您应该已经得到警告。 有关详细信息,请参见RSA_generate_key(3)

您的代码应类似于:

BIGNUM* exp = BN_new();
ASSERT(exp != NULL);

int rc = BN_set_word(exp, RSA_F4);
ASSERT(rc == 1);

RSA* rsa = RSA_new();
ASSERT(rsa != NULL);

rc = RSA_generate_key_ex(rsa, 2048, exp, NULL);
ASSERT(rc == 1);

一定要打电话BN_freeBIGNUM ,并RSA_freeRSA指针。


 RSA *privrsa = NULL; d2i_RSAPrivateKey(&privrsa,(const unsigned char **)&priv,privl); RSA *pubrsa = NULL; d2i_RSAPublicKey(&pubrsa,(const unsigned char **)&pub,publ); 

为此,您似乎正在尝试分离公共密钥和私有密钥。 对于这一点,使用RSAPublicKey_dupRSAPrivateKey_dup 请参阅将公用密钥和专用密钥与RSA密钥对变量分开


对我来说不清楚您正在尝试以下操作。 您应该说明您要做什么...

pub_l = malloc(sizeof(pub_l));
*pub_l = i2d_RSAPublicKey(pRSA,pub);
priv_l = malloc(sizeof(priv_l));
*priv_l = i2d_RSAPrivateKey(pRSA,priv);

我只是在猜测,但我要说的全是错。 sizeof(priv_l)是指针的大小,因此是4或8个字节。 您还将覆盖调用者传递的指针。

另请参见OpenSSL的rsautl无法加载使用PEM_write_RSAPublicKey创建的公共密钥 它讨论了如何使用SubjectPublicKeyInfoPrivateKeyInfo以ASN.1 / DER和PEM格式保存密钥。

通过写入{Public | Private} KeyInfo ,OID将被写入密钥。 这对互操作非常重要。 您还使用了RSA* (甚至是EVP_PKEY* ),而不是字节数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM