c中的OpenSSL命令用于获取RSA中公钥的模数

我们想在C中找到一个OpenSSl方法,它只使用RSA从公钥中获得模数。 但是我们不确定使用哪种方法。 d2i_RSAPublicKey函数是否有效,但我们不确定它需要什么参数? “

以下open ssl命令的c方法是什么,它只提取模数:

$ openssl ssl rsa -inform der -pubin -text < 12120862.key Public-Key: (1024 bit) Modulus: 00:81:1f:1d:00:7e:d0:c7:e2:2f:31:3d:0d:f0:a8: ab:c1:ea:66:ba:af:1d:a4:eb:b3:fd:51:58:1c:1d: 81:ae:f0:99:9e:5c:26:67:b5:41:14:28:79:c0:29: e5:56:96:06:b7:4b:a0:c9:7f:41:46:9a:7e:85:10: a0:91:ea:58:bd:78:78:6d:3c:07:2a:3d:61:f3:ed: 42:8b:1e:dc:6d:2d:21:41:7a:e8:15:51:0d:75:84: be:20:8c:76:43:8b:4b:67:6b:49:09:e9:20:a1:11: 53:a0:d9:30:b1:c2:27:a6:09:e1:56:36:ed:7e:9b: 23:e2:df:5b:bd:c5:66:ca:c5 Exponent: 65537 (0x10001) writing RSA key -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCBHx0AftDH4i8xPQ3wqKvB6ma6 rx2k67P9UVgcHYGu8JmeXCZntUEUKHnAKeVWlga3S6DJf0FGmn6FEKCR6li9eHht PAcqPWHz7UKLHtxtLSFBeugVUQ11hL4gjHZDi0tna0kJ6SChEVOg2TCxwiemCeFW Nu1+myPi31u9xWbKxQIDAQAB -----END PUBLIC KEY----- 

以下open ssl命令的c方法是什么,它只提取模数

简短回答……鉴于RSA结构:

 RSA* rsa = ...; BIGNUM* n = rsa->n; 

然后,使用BN_print_fp

 BN_print_fp(stdout, n); 

或者,使用BN_bn2dec

 fprintf(stdout, "%s", BN_bn2dec(n)); 

或者,使用ASN1_bn_print

 int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf, int off) 

ASN1_bn_print来自下面的长答案,它为您提供了示例中显示的格式。


答案很长…我相信密钥是用RSA_print_fp打印的,它最终以对各种RSA参数的ASN1_bn_print调用结束。 这是小道的一部分:

 $ grep -R RSA_print_fp * crypto/rsa/rsa.h:int RSA_print_fp(FILE *fp, const RSA *r,int offset); crypto/rsa/rsa_err.c:{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"}, crypto/rsa/rsa_prn.c:int RSA_print_fp(FILE *fp, const RSA *x, int off) ... 

RSA_print_fp

 int RSA_print_fp(FILE *fp, const RSA *x, int off) { BIO *b; int ret; if ((b=BIO_new(BIO_s_file())) == NULL) { RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB); return(0); } BIO_set_fp(b,fp,BIO_NOCLOSE); ret=RSA_print(b,x,off); BIO_free(b); return(ret); } 

RSA_print

 int RSA_print(BIO *bp, const RSA *x, int off) { EVP_PKEY *pk; int ret; pk = EVP_PKEY_new(); if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x)) return 0; ret = EVP_PKEY_print_private(bp, pk, off, NULL); EVP_PKEY_free(pk); return ret; } 

EVP_PKEY_print_private位于crypto/evp/p_lib.c

 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { if (pkey->ameth && pkey->ameth->priv_print) return pkey->ameth->priv_print(out, pkey, indent, pctx); return unsup_alg(out, pkey, indent, "Private Key"); } 

进入“方法”后, 请不要遵循RSA_get_default_method 。 相反,找到priv_print

 $ grep -R priv_print * | grep -i RSA crypto/rsa/rsa_ameth.c:static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, crypto/rsa/rsa_ameth.c: rsa_priv_print, 

rsa_priv_print

 static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) { return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); } 

接下来, do_rsa_print

 static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv) { ... str = "Modulus:"; s = "Exponent:"; if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err; if (!ASN1_bn_print(bp,s,x->e,m,off)) goto err; if (priv) { if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off)) goto err; if (!ASN1_bn_print(bp,"prime1:",x->p,m,off)) goto err; if (!ASN1_bn_print(bp,"prime2:",x->q,m,off)) goto err; if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off)) goto err; if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off)) goto err; if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off)) goto err; } ... } 

我将最终的ASN1_bn_print跟踪留给读者。 它添加了冒号(:)和换行符( \n )。 你可以在crypto/asn1/t_pkey.c找到它。


以下是使用ASN1_bn_print

 RSA* rsa = RSA_new(); ... BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE); ... int req = BN_num_bytes(rsa->n) + 4; ptr = OPENSSL_malloc(req); rc = ASN1_bn_print(bio, "Modulus:", rsa->n, ptr, 0); ASSERT(rc == 1); ... 

运行上面的程序将产生:

 $ ./test-openssl.exe Modulus: 00:bb:bb:cf:ac:58:a9:25:2c:08:37:4d:4d:1d:0c: 5b:7d:a7:ba:de:7b:31:9a:5e:40:61:1f:6d:de:f9: b4:48:15:a3:8c:2a:12:a9:10:fb:66:12:a4:3f:9c: 0d:7f:80:94:b1:63:91:05:96:f0:48:e5:7d:76:8a: d0:26:dc:54:43 

我正在寻找通过接受公钥来返回struct rsa的ac函数

为此,您可能需要PEM_read_RSAPrivateKeyPEM_read_PUBKEY 。 还有一些生物读物。 见pem(3)

PEM_read_RSAPrivateKey返回RSA*

PEM_read_PUBKEY返回EVP_PKEY*如果是RSA密钥,则可以使用EVP_PKEY_get1_RSA获取RSA*get1表示引用计数被RSA_free ,因此请RSA_free在其上调用RSA_free

要确定EVP_PKEY*是否为RSA密钥,请使用EVP_PKEY_get_type 。 您将收到EVP_PKEY_RSAEVP_PKEY_RSA2