1

According to rfc5208, https://www.rfc-editor.org/rfc/rfc5208#page-3 , pkcs8 keys can have optional attributes.

How can I generate an RSA key with these optional attributes? I have only seen the option for openssl genpkey pkeyopt, which i can specify things like rsa_keygen_bits:2048 to set the keysize, but if I wanted to do sometihng like add an optional attribute for a name associated with that private key, how would I do that?

Community
  • 1
  • 1
Derek
  • 11,715
  • 32
  • 127
  • 228
  • I presume only by looking up the PKCS#8 structure generation in OpenSSL and make additions to it. I've not seen that used by anything, and it would mean implementing [this](https://www.itu.int/ITU-T/formal-language/itu-t/x/x501/2012/InformationFramework.html). Which just shows that somebody went ape-shit on ASN.1 definitions and was probably ignored by anybody that *could*. – Maarten Bodewes Nov 02 '19 at 13:15
  • I take this to mean you're saying I'm probably better off to rely on cert based encryption scheme? – Derek Nov 03 '19 at 19:25
  • Um, that's quite another use case probably. Then you assign the attributes to the *public key*. And yes, that normally makes more sense. If you have the private key then you probably know what you can do with it. – Maarten Bodewes Nov 04 '19 at 00:33
  • I thought there would be a use case where if you had a jumble of private keys, lets say, you'd have a way of identifying which ones were which. – Derek Nov 04 '19 at 02:55
  • Yeah, that's an OK use case. However, in practice I see that they are identified by external means. Note that you can uniquely identify them by the modulus, so there is a way to distinguish between them that way - even if it is rather RSA specific. – Maarten Bodewes Nov 04 '19 at 12:34

1 Answers1

1

You can't do it with commandline, which may be fortunate as that wouldn't be a programming problem and thus not really ontopic for SO. So here's a minimal programmed example:

/* SO58667890 19nov04 PKCS8 attribute */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>

void err (const char * s, int n){ fprintf(stderr, "%s:%d\n", s,n); ERR_print_errors_fp (stderr); exit(1); }

int main (int argc, char** argv){
  if( argc < 4 ){ fprintf(stderr, "Usage: %s privkey.pem attrname attrvalue\n"); return 0; }
  int rv;

  BIO *bio = BIO_new_file (argv[1],"r");
  if( !bio ) err("BIO_new_file-r",0);
  EVP_PKEY *pkey = PEM_read_bio_PrivateKey (bio, NULL, NULL,NULL);
  if( !pkey ) err("PEM_read_bio_PrivateKey",0);
  PKCS8_PRIV_KEY_INFO *p8inf = EVP_PKEY2PKCS8 (pkey);
  if( !p8inf ) err("EVP_PKEY2PKCS8",0);

  int nid = OBJ_txt2nid (argv[2]);
  if( nid == NID_undef ) err("OBJ_txt2nid",nid); 

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL 
  rv = PKCS8_pkey_add1_attr_by_NID (p8inf, nid, V_ASN1_IA5STRING, (unsigned char*)argv[3], strlen(argv[3]));
  if( !rv ) err("PKCS8_pkey_add1_attr_by_NID",rv);
#else
  if( !X509at_add1_attr_by_NID (&p8inf->attributes, nid, V_ASN1_IA5STRING, (unsigned char*)argv[3], strlen(argv[3])) )
    err("X509at_add1_attr_by_NID",0);
#endif

  bio = BIO_new_file (argv[1],"w");
  if( !bio ) err("BIO_new_file-w",0);
  rv = PEM_write_bio_PKCS8_PRIV_KEY_INFO (bio, p8inf);
  if( !rv ) err("PEM_write_bio_PKCS8info",rv);
  rv = BIO_free(bio);
  if( !rv ) err("BIO_free",rv);

  return 0;
}

However, as Maarten commented, these attributes are very rarely used. I've seen at least one case here where Java didn't implement them at all. In the PKI world, including S/MIME and SSL/TLS, you usually have an X.509 (or PKIX) certificate for the publickey matching your privatekey, and the certificate has lots of useful information about the identity of the owner and authorized usage of the key -- and this information is in a form programs largely understand and can use (although there are now and then issues with one party or system creating a new certificate extension that isn't understood by another party or system). For example, when you look in Windows certmgr or MacOS keychain, you don't see a privatekey as such; you see a certificate with a privatekey attached to it.

dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70