> From: [email protected] On Behalf Of redpath
> Sent: Monday, 10 September, 2012 16:33

> To give out my public key, I need to be put it into a certificate with
> my name, and signed by my own private key etc.. This process is call
> generating a self-signed public key certificate. OpenSSL can do this
> in a single command 
> "openssl req -new -x509" 
> 
Maybe. Creating a self-signed cert is *one* way of distributing 
your publickey, but not the only way. If "I need" means that you have 
chosen this method, or your boss or customer or someone has chosen it, 
fine. If "I need" means you think this is the only way, it's not.

FWIW openssl commandline can actually do generate-keypair and generate 
self-signed cert in one operation, 'req -newkey parms -x509'.

> as shown in the following command window session:
> test.pem contains both public and private RSA keys, so here 
> is the process
> 
> So create an RSA key pair called test.pem
>     openssl genrsa -out  test.pem 2048
> Extract the public key only
>     openssl rsa -in test.pem -pubout -out testpublic.pem
> 
The "Extract" part is okay but unneeded, see below.

> Then create a certificate
>     openssl req -new -key testpublic.pem -inform pem -x509 
> -days 3650 -out testpublic.cert 

No. 'req' needs privatekey to generate either a CSR or selfsigned 
cert, although only the publickey goes *in* the CSR or cert.

>     openssl x509 -in testpublic.cert -noout -text
> 
This step isn't needed, it's only to look at what happened.

> I can then use the function to open this X509 Certficate.
>     fp = fopen("testpublic.cert","rb");
>     X509 *cert=PEM_read_X509(fp,NULL,NULL,NULL);
> 
Nit: you should always check if fopen returned null (failed) 
before using the filepointer.

Aside: PEM-format files are text and the distinction between 
"b" binary and text files in (portable) C doesn't matter to them.
Mode just "r" is fine, and even preferable on some obscure systems 
you probably won't encounter nowadays.

> So now I have test.pem (RSA keys) testpublic.pem (public key) and
> testpublic.cert (x509 cert with piublic key).
> 
> Below is code that uses the PEMs directly.
> 
>     FILE *fp = fopen("test.pem","rb");
>     RSA *rsapriv=NULL;
>     rsapriv= PEM_read_RSAPrivateKey(fp,&rsapriv,NULL,NULL);
>     fclose(fp);
> 
>     fp = fopen("testpublic.pem","rb");
>     RSA *rsapub=NULL;
>     rsapub= PEM_read_RSA_PUBKEY(fp,&rsapub,NULL,NULL);
>     fclose(fp);
>     
Aside: in OpenSSL (although not always in other systems) an RSA 
privatekey is actually the keypair and includes the publickey, 
so you don't need a separate file or structure.

>     unsigned char *name= (unsigned char *)"richard redpath";
>     unsigned char to[1024];
>     int blocksize= RSA_size(rsapub)-41;
>     printf("curious Blocksize is %d\n",blocksize);
>     int rc= RSA_public_encrypt(strlen((char
> *)name)+1,name,to,rsapub,RSA_PKCS1_OAEP_PADDING);
>     if (rc!=(-1))
>          printf("Encrypt %d bytes returned\n",rc);
> 
>     unsigned char result[1024];
>     rc= 
> RSA_private_decrypt(128,to,result,rsapriv,RSA_PKCS1_OAEP_PADDING);
>     printf("Decrypt rc=%d \n",rc);
>     printf("result is [%s]\n",result);
> 
128 bytes is correct only for a 1024-bit RSA key (in which case 
your 'to' and 'result' buffers are bigger than needed) but your 
(example?) key above was 2048-bit. If you want to handle varying 
key sizes, use the length returned from RSA_public_encrypt, or 
RSA_size, and allocate the buffer that size (or check it is). 
If you transmit RSA-encrypted information from one system (or program) 
to another, which is usually the reason people do encryption, you 
must transmit it in a fashion that preserves its length. In particular, 
do *not* treat it as a C string (terminated by NUL) or a line 
(terminated by newline). You may wish to convert it to a form 
that can be treated as a string and/or line, like hex or base64.
(The same generally applies to other modern crypto algorithms, 
except stream ciphers have ciphertext the same length as plaintext 
and in some cases plaintext length is otherwise known.)

Note that encrypting (and decrypting) data directly with RSA 
is rarely done, so your scheme here almost certainly won't be 
interoperable with anyone else -- if you care about that. 
(With older PKCS#1 'type2' padding it was also insecure against 
some oracle attacks, but OAEP fixes that.)

> The question I have is that I want to hand out my X509 Public 
> key and have
> code that can use it to decpher. I can use this function to open the
> certificate
> 
>    fp = fopen("testpublic.cert","rb");
>     X509 *cert=PEM_read_X509(fp,NULL,NULL,NULL);
>     if (cert!=NULL)
>       printf("CERT is good***\n");
> 
> But how can I get the Public key from this x509? So I can use
> decryption of data? In this example I use the public key PEM directly
> and thats what I should not hand out.
> 
The publickey can only encrypt, you need the privatekey to decrypt, 
as the code you quoted above correctly does. Did you actually write 
that code, or are you just copying random things off the Internet?

If you want the publickey from a cert to encrypt (or verify) with 
EVP (openssl's more convenient high-level), call X509_get_pubkey or 
do the same thing it does: X509_PUBKEY_get(x509->cert_info->key) .
If you want to do lowlevel operations, easiest to get the EVP 
key first and then extract the RSA key from it.

<snip rest>

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to